2012-01-07 3 views
0

Я достиг двух блоков преткновения при программировании программы калькулятора. Хотя я получаю правильный результат от калькулятора и правильно печатаю для сложения, вычитания и умножения, я просто печатаю символ ? для результата деления. См. Код ниже.C программирование на μ-контроллере: printf() и FDEV_SETUP_STREAM?

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», но у нее не было десятичной точки, связанной с ней, хотя это поплавок.

второй вопрос:

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

//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_strstdin, а затем распечатает всю строку введенной пользователем команды на экране.

+1

Попробуйте '(float) * val1/* val2' вместо' c' в 'printf' –

+0

Также в вашем втором коде должно быть' '\ n'' –

+0

@VinayakGarg: Почему оценка в' printf() 'вызов имеет значение? –

ответ

1

Для вашего вопроса-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 
$ 

Wrt вопрос-2:

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

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

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

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

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

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() требуют знаний, которых у меня нет.

Однако, компилятор Си должен сказать вам, что:

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"; 

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

Смежные вопросы