C программирование на µ-контроллере: printf () и FDEV_SETUP_STREAM? - PullRequest
0 голосов
/ 07 января 2012

Я достиг двух камней преткновения при программировании программы калькулятора.Хотя я получаю правильный результат из калькулятора и правильно печатаю для сложения, вычитания и умножения, я просто печатаю символ ? для результата деления.Пожалуйста, обратитесь к приведенному ниже коду.

static void calculate(int *val1, int *val2, char *op){
float a = *val1;
float b = *val2;
float c = a/b;

   /*
   A stands for addition, B for sub, C for mul, D for div
   I have already verified that the right operation is being
   performed
   */

if(strcmp(op,"A")==0)
    {
    printf("%i \n\r", *val1+*val2);
}else if(strcmp(op,"B")==0)
    {
    printf("%i \n\r", *val1-*val2);
}else if(strcmp(op,"C")==0)
    {
    printf("%i \n\r", *val1 * *val2);
}else if(strcmp(op,"D")==0)
    {
    printf("%f \n\r", c);
}
}  

Я использую реальный термин для печати результатов с моего микроконтроллера Atmega 32.

В отладчике я подтвердил, что float c имеет правозначение, когда операция, выбранная пользователем, является делением «D», но, похоже, с ним не связана десятичная точка, хотя она и является плавающей точкой.

2-й вопрос:

Мне было интересно, могу ли я использовать массив символов (строку), как это:

//please note that below I am just simulating user keystrokes on a keypad attached to a
//microcontroller just for simplifying the problem.

  char a[20] = {1,2,3,4,5,\n};
  FILE keypad_str = FDEV_SETUP_STREAM(NULL, a, _FDEV_SETUP_READ);

То, что я пытаюсь выше, пытаетсячтобы придумать стратегию, позволяющую мне распечатывать каждую пользовательскую клавишу, нажимайте сразу, вместо того, чтобы keypad_str stdin, а затем выводите на экран всю строку введенной пользователем команды.

Ответы [ 2 ]

2 голосов
/ 07 января 2012

Вы не проверяете деление на ноль перед выполнением деления.

Не ясно, почему вы всегда делите, даже если операция является сложением, вычитанием или умножением.Делать это следует только тогда, когда это необходимо:

else if (strcmp(op, "D")==0)
{
    float a = *val1;
    float b = *val2;
    if (*val2 == 0)
        printf("Divide by zero error\n");
    else
    {
        float c = a / b;
        printf("%f\n", c);
    }
}

Я оставил переменную c на месте, поскольку это облегчает отладку значений.

Ничто из этого не объясняет вопросаОтметить вывод.

(Нужно ли указывать компилятору C на микроконтроллере Atmega 32 включить поддержку плавающей запятой в библиотеке? Это может объяснить вопросительный знак.)

Я бывыбрали строки "+", "-", "*" и "/" в качестве мнемоники для операций;Тогда я бы не стал комментировать, объясняя, что означают операции.

Обычно вы не включали бы возврат каретки в формате.Когда вы это делаете, он обычно предшествует, а не следует за новой строкой.Также непонятно, зачем вам нужен пробел в конце строк вывода.

Некоторые вопросы о FDEV_SETUP_STREAM () требуют знаний, которых у меня нет.

ОднакоКомпилятор C должен сообщить вам, что:

char a[20] = {1,2,3,4,5,\n};

недопустимо.Вы можете иметь в виду любой из них;оба они действительны, но довольно различны:

  char a[20] = { 1, 2, 3, 4, 5, '\n' };
  char a[20] = { '1', '2', '3', '4', '5', '\n' };

Приведенные выше инициализаторы могут быть сокращены до:

 char a[20] = "\001\002\003\004\005\n";
 char a[20] = "12345\n";

Это подчеркивает разницу (и нет, двойные нули не являютсястрого необходимо, но помогите сделать точку).

1 голос
/ 07 января 2012

В вашем вопросе-1 возникло несколько проблем, поэтому я переписал вашу программу следующим образом:

#include <stdio.h>

static void calculate(int val1, int val2, char op) 
{
    switch(op) {
        case 'A':
            printf("%d+%d = %d \n", val1, val2, val1 + val2);
            break;
        case 'B':
            printf("%d-%d = %d \n", val1, val2, val1 - val2);
            break;
        case 'C':
            printf("%d*%d = %d \n", val1, val2, val1 * val2);
            break;
        case 'D':
            if (val2 == 0) {
                printf("can't divide by 0\n");
                break;
            }                     
            printf("%d/%d = %.2f \n", val1, val2, (float)val1/(float)val2);
            break;
        default:
            break;
    }   

    return;
}  

int main(void) 
{
    int a = 10, b = 20; 
    char op = 'D';
    calculate(a, b, op);
    op = 'A';
    calculate(a, b, op);
    return 0;
}

Вывод:

$ ./a.out 
10/20 = 0.50 
10+20 = 30  
$ 

По вопросу-2:

char a[20] = {1,2,3,4,5,\n};

недопустимо, вместо этого оно должно быть следующим:

char a[20] = {'1', '2', '3', '4', '5', '\n'};
...