Проанализируйте переменную в C и затем решите, что делать - PullRequest
0 голосов
/ 16 апреля 2020

Привет, я все еще C новичок и начинающий кодер,

Я пытался разработать какой-то элементарный интерфейс через командную строку и хотел бы реализовать это, когда пользователь вставляет что-то, что не является числом, l oop ломается и движется

(я мечтаю, чтобы он проверял, когда ввод равен слову new) В любом случае вот мой фрагмент кода:

do {
    printf("\nInsert the score you obtained: ");
    scanf("%d", &avg);
} while ( isdigit(avg) == 0 );

По существу, до тех пор, пока ввод не станет числом, он будет продолжать работать, а когда вставлено что-то, не являющееся целым числом, он должен выйти из l oop.

Ответы [ 2 ]

0 голосов
/ 17 апреля 2020

Чтобы получить что-то, что не является целым числом, вы должны scanf что-то, что не является целым числом.

char* input;
do {
    printf("\nInsert the score you obtained, or exit to quit: ");
    scanf("%[^/n]", input);
    ...

Теперь, когда у вас есть переменная, которая может содержать и "выход", и какое-то число (представленное в виде символов), вам нужно принять решение на основе того, какой тип ввода вы получили.

char input[80];
do {
    printf("\nInsert the score you obtained, or exit to quit: ");
    scanf("%[^/n]", &input);
while ( strncmp(input, "exit", 4) == 0 );

это также означает, что вам, возможно, придется преобразовать «строку» числа в числовое значение.

char input[80];
do {
    printf("\nInsert the score you obtained, or exit to quit: ");
    scanf("%[^/n]", &input);
    int number = convert_to_number(input);
while ( strncmp(input, "exit", 4) == 0 );

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

do {
    printf("\nInsert the score you obtained, or exit to quit: ");
    scanf("%[^/n]", &input);
    if ( looks_like_number(input) ) {
        int number = convert_to_number(input);
    }
} while ( strncmp(input, "exit", 4) == 0 );

и, наконец, вам может потребоваться собрать несколько входов, например l oop примет их сейчас

do {
    printf("\nInsert the score you obtained, or exit to quit: ");
    scanf("%[^/n]", &input);
    if ( looks_like_number(input) ) {
        sum = add(sum, convert_to_number(input));
    }
} while ( strncmp(input, "exit", 4) == 0 );

Это только одно решение из очень большого числа возможных способов сделать это.

Это решение также может быть улучшено (например, обрезка пробела вокруг флага «выход», чтобы пользователь мог набрать «выход» или «выход», чтобы уйти. Можно также сделать l oop не oop, поскольку вопрос, кажется, подразумевает ввод одного числа или «выход» один раз, в то время как al oop будет разрешать много чисел до тех пор, пока не будет напечатан exit.И можно удалить глупую функцию add, которая использовалась только для демонстрации с помощью Слово очень ясная идея, когда + может подойти.

Даже если вышеуказанный подход l oop / не идеально подходит для ваших потребностей, пожалуйста, внимательно посмотрите на него, потому что идеи в нем может быть использован для успеха вашей программы.

Кроме того, не используйте isdigit для проверки всего числа. Смотрите sscanf, что похоже на printf, но для чтения материала из строк . sscanf ваш номер вне строки и проверьте возвращаемое значение, чтобы увидеть, нашли ли вы число в строке.

0 голосов
/ 16 апреля 2020

isdi git (с прототипом int isdigit (int Test_Character);) не подходит для тестирования при определении, является ли int числом digit или . isdigit() используется скорее для проверки, является ли одиночный символ десятичным числом git (0-9). Входными данными для этой функции должен быть символ с целочисленным значением от 0 до 255. (обратитесь к ASCII таблице , чтобы увидеть, что это за значение.)

Правильно сделать здесь: определить, правильно ли scanf преобразовал входное значение.

Функция scanf () имеет прототип с возвращаемым значением, указывающим на успех или неудачу, но ваш код в настоящее время не проверяет его.

Итак, в итоге, ваш while l oop может быть записан с использованием возврата scanf():

int main(void)
{
    int count = 0;
    int avg= 0;


    do
    {
        printf("\nInsert the score you obtained: ");
        count = scanf("%d", &avg);

    }while(count > 0);               //stays in loop for any numeric value
    // } while ( isdigit(avg) == 0 );//Note; input containing decimal points will be truncated
                                     //to contain only integer portion



    return 0;
}

До тех пор, пока ввод является целым числом c value, scanf вернет count в качестве положительного значения (количество сканированных значений правильно).

Например:
123, -123, 8, 0 все позволяют l oop продолжать.
a, dfg все приведет к неудачной попытке преобразовать входные данные в число c и вернуть EOF (-1)

Обработка как string представление чисел c: (аналогичное поведение с альтернативным кодированием подход.)

Я обещал показать, как использовать strtol () :

Путем изменения спецификатора формата ввода с "%d" на "%s", scanf() будет читать входное значение 123 в виде строки: "123". Когда ввод вводится в вашу программу как строковое представление чисел c, он должен быть преобразован в число числового типа c, прежде чем его можно будет использовать. strtol() может быть использовано для этого преобразования.

Вот модификация вашей исходной программы, иллюстрирующая, как это можно сделать:

int main(void)
{
    int count = 0;
    char avg[20] = {0};//changed to string variable
    long val = 0;
    bool success = FALSE;

    do
    {
        printf("\nInsert the score you obtained: ");
        count = scanf("%s", avg);//changed format specifier to read strings
        if(count)
        {
            success = parseLong(avg, &val);//see correct usage of strtol in function
        }

    }while(success); //Stays in loop for any numeric input.  
                     //Note: input containing decimal values 
                     //will be truncated to contain integer portion only.
    return 0;
}

bool parseLong(const char *str, long *val)
{
    char *temp;
    BOOL rc = TRUE;
    errno = 0;
    *val = strtol(str, &temp, 0);

    if (temp == str || ((*val == LONG_MIN || *val == LONG_MAX) && errno == ERANGE))
        rc = FALSE;

    return rc;
} 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...