Я сделал калькулятор в C, но я хочу исправить некоторые ошибки, связанные с scanf - PullRequest
2 голосов
/ 30 апреля 2020

Итак, я сделал калькулятор в C, и он работает, но я хочу избавиться от некоторых ошибок, связанных с scanf. Проблемы, с которыми я столкнулся:

  1. , если я введу 5 5, и число 1, и число 2 будут равны 5. В любом случае я могу игнорировать пробел и принять число 55?
  2. если я введу 5 c, он будет читать номер 1 как 5, затем он активирует отказоустойчивый (из-за 'c') и закроется.
  3. , если я введу очень большое число, он даст ложный результат. В любом случае, я могу установить ограничение в 15 чисел?

Я думаю, что должен заменить scanf на fgets, но я не знаю, как это реализовать из-за того, как я написал свой код. Есть идеи?

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

void print_help(void);

int main (void)
{   
    float nr1, nr2, rezultat;
    char operatia;
    int failsafe;                           //failsafe
    print_help();                           //show help

    printf("Salut! Am nevoie de un numar: "); //first number
    failsafe = scanf("%f", &nr1);
        if (failsafe == 1)
        {
            printf("Ok. Mersi!\r\n");
        }
        else
        {
            printf("bruh..");
            sleep(2);
            exit(-1);
        }

    printf("Am nevoie de inca un numar: ");     //second number         
    failsafe = scanf("%f", &nr2);
        if (failsafe == 1)
        {
            printf("Haha! foarte buna alegere.\r\n");
        }
        else
        {
            printf("bruh..");
            sleep(2);
            exit(-1);
        }                           
    printf("Bun. Ce operatie vrei sa aplic? (scrie doar unul dintre simbolurile prezentate mai sus)\n Raspunsul tau: ");    //asking for the operation symbol           
    scanf(" %c", &operatia);          

    switch (operatia)                       //------calculare------
        {
            case '+':
                rezultat = nr1 + nr2;
                break;
            case '-':
                rezultat = nr1 - nr2;
                break;                                  
            case '/':
                if (nr2 == 0)
                {
                    printf("nah man. im out.");
                    sleep(2);
                    exit(-2);
                }
                rezultat = nr1 / nr2;
                break;
            case '*':
                rezultat = nr1 * nr2;
                break;
            default:
                printf("bruh..");
                sleep(2);
                exit(-1);   
        }

            printf("Rezultatul tau este: %.2f", rezultat);   //afisare 
            sleep(1);                                        //
            printf("\r\nThank you and...");                  //
            sleep(1);                                        //afisare rezultat
            printf("Goodbye!");                              //
            sleep(3);                                        //
    return 0;
}   
//-----------behind the scenes-----------
void print_help(void)
{
    printf("-----------------------------\n\r");
    printf("\tCalculator v1.2\r\n\r\n");
    printf("-> simbolul pentru adunare este:  +   \r\n\r\n");
    printf("-> simbolul pentru scadere este:  -   \r\n\r\n");
    printf("-> simbolul pentru inmultire este:  *   \r\n\r\n");
    printf("-> simbolul pentru impartire este:  /   \r\n\r\n");
    printf("-----------------------------\n\r");

    return;
}

Ответы [ 2 ]

2 голосов
/ 30 апреля 2020

Как предложено Weather Vane, вы можете изменить прочитанный тип данных и, следовательно, увеличить максимальное число!

Я предлагаю прочитать страницу Википедии с типом данных C, чтобы выбрать наиболее интересующий вас тип. и который соответствует вашим потребностям больше всего! (https://en.wikipedia.org/wiki/C_data_types) Если вам нужно хранить еще большие числа, вам потребуется реализовать собственное решение, например, сохранить массив preffered_data_type.

Насколько мне известно, scanf не позволяет анализировать 5 5 как 55. Если вы хотите sh реализовать эту функцию, вам нужно будет извлечь ввод из командной строки в виде строки, а затем проанализировать ее самостоятельно: (

Это простая реализация желаемого поведения с использованием getline для разбора int с.

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char const *argv[])
{
    char *buffer = NULL;
    char *number;
    ssize_t response;
    unsigned int j = 0;
    size_t n = 0;

    printf("> ");
    response = getline(&buffer, &n, stdin);
    number = calloc(1, strlen(buffer) + 1);
    for (unsigned int i = 0; buffer[i]; i++) {
        if (buffer[i] >= '0' && buffer[i] <= '9') {
            number[j] = buffer[i];
            j++;
        }
    }
    printf("The number you entered: %d\n", atoi(number));
    return 0;
}

Выходы:

➜  Desktop ./a.out
> 5 5     
The number you entered: 55
➜  Desktop 
1 голос
/ 30 апреля 2020

Вы можете использовать fgets для чтения ввода как строки. Затем, получить номер или что-то, что вы хотите с этой строкой. Использование scanf не может прочитать всю строку ввода, поскольку оно читает слово за словом из ввода.

Для удаления пробела в строке вы можете увидеть Удаление пробелов из строки в C.

Для преобразования строки в число с плавающей запятой вы можете использовать функцию strtof. Подробнее на Как преобразовать строку в число с плавающей точкой?

Небольшой пример того, как вы можете получить входную строку и сделать с ней что-то, что вы хотите:

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>


void remove_spaces(char* s) {
    const char* d = s;
    do {
        while (*d == ' ') {
            ++d;
        }
    } while (*s++ = *d++);
}

void copy_str(char *s) {
    const char* d = s;
    int i = 0;
    while (isdigit(*d)) {
        s[i] = *d++;
        i++;
    }
    s[i] = '\0';
}

int main()
{
    float number;
    char str[30];
    fgets(str, sizeof(str), stdin);
    remove_spaces(str);
    int len1 = strlen(str);
    printf("remove_spaces: %s\n", str);
    copy_str(str);
    int len2 = strlen(str);
    if(len1 > len2+1) {
        number = strtof(str,NULL);
        printf("FALSE -- number = %f\n", number);
        return 0;
    }
    printf("copy_str: %s\n", str);
    if(strlen(str) > 15) {
        printf("too long\n");
        return 0;
    }
    number = strtof(str,NULL);
    printf("number = %f\n", number);
    printf("Hello World");

    return 0;
}

Выходные данные 1: символ пробела содержимого строки.

55 55                                                                                                                     
remove_spaces: 5555                                                                                                       

copy_str: 5555                                                                                                            
number = 5555.000000                                                                                                      
Hello World 

Выход 2: буквенный символ содержимого строки.

55 55c                                                                                                                  
remove_spaces: 5555c                                                                                                    

FALSE number = 5555.000000 

Выход 3: строка слишком длинная.

123456789101111111                                                                                                      
remove_spaces: 123456789101111111                                                                                       

copy_str: 123456789101111111                                                                                            
too long
...