Проверка только целых чисел и строк без использования только fgets - PullRequest
0 голосов
/ 11 февраля 2020

Я пытаюсь получить целое число из командной строки без scanf(), но с использованием только fgets(), как я могу отфильтровать fgets() contents, сообщающее об ошибке, если я вставляю символ или строку? Проблема в том, что когда я вставляю что-то другое, например символ или строку, функция atoi() (необходимая для выполнения некоторых операций в моем алгоритме) преобразует эту строку в 0, в то время как я предпочитаю выходить, если введенное значение отличается от целого числа. Вот часть кода:

.....
char pos[30];
printf("\n Insert a number: ");
fgets (pos, sizeof(pos), stdin);
if (atoi(pos) < 0) //missing check for string character
    exit(1);
else{
printf ("%d\n", atoi(pos)); //a string or character converted through atoi() gives 0
}
int number = atoi(pos);
......

Ответы [ 3 ]

2 голосов
/ 11 февраля 2020

Как сказали комментаторы, используйте strtol(), а не atoi().

. Проблема с strtol() состоит в том, что она выдаст ошибку ERANGE (согласно спецификации), когда преобразованное число не будет вписываться в длинный тип. Поэтому, если вы попросите его преобразовать " 1", это даст 1. Если вы попросите его преобразовать "apple", он вернет 0 и установит endptr для указания ошибки.

Очевидно, вам необходимо решить, будет ли " 12" допустимый ввод или нет - strtol() с удовольствием пропустит начальный пробел.

EDIT : функция обновлена, чтобы лучше обрабатывать ошибки с помощью endptr.

// Convert the given <text> string to a decimal long, in <value>
// Allow a string of digits, or white space then digits
// returns 1 for OK, or 0 otherwise
int parseLong( const char *text, long *value )
{
    int rc = 0;    // fail
    char *endptr;  // used to determine failure

    if ( text && value )
    {
        errno = 0;                               // Clear any errors
        *value = strtol( text, &endptr, 10 );    // Do the conversion

        // Check that conversion was performed, and
        // that the value fits in a long
        if ( endptr != text && errno != ERANGE ) 
        {
            rc = 1;  // success
        }
    }

    return rc;
}
0 голосов
/ 11 февраля 2020

Я решил самостоятельно, используя strcspn(), прежде чем проверять через isdigit() целочисленный тип, без strcspn () он бы всегда возвращал -1

0 голосов
/ 11 февраля 2020

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

Я думаю, что вы ищете, это "целое число" функция. В стандартной библиотеке C ctype.h есть функции, называемые isalpha и isdigit.

https://www.programiz.com/c-programming/library-function/ctype.h/isalpha

Таким образом, вы можете сделать функцию, которая проверяет, содержит ли char * только цифры c символов.

int str_is_only_numeric(const char *str) {
    int i = 0;
    while (str[i] != '\0') {
        if (isdigit(str[i++]) == 0) {
            return -1;
        }
    }
    return 0;
} 

Вот рабочий пример функции: https://onlinegdb.com/SJBdLdy78

...