Как я могу контролировать правильность ввода с помощью strtok & sscanf? - PullRequest
2 голосов
/ 11 ноября 2019

Мне нужно получить ввод строки с числами, разделенными пробелами (может быть многократными пробелами).

Код, который я написал ниже, печатает Invalid number только вход имеет такую ​​форму:

8a (символ после числа).

Например, если я введу a b c, он не напечатает Invalid number и не перейдет с программой.

В основномМне нужно проверить, содержит ли строка только цифры и пробелы .

Если он не выбрасывает Invalid number

Если он есть - заполнить * массив чиселс введенными этими числами.

        printf("Enter numbers:\n");
        fgets (str, sizeof(int)*(size+1)+size*size, stdin);
        token=strtok(str," ");
        for(int i=0; (i<size) && (token!=NULL); i++) {
            if(sscanf(token,"%d%c",&numbers[i],&ch) == 2 && (ch != ' ' && ch != '\n')) {
                printf("Invalid number\n");
                return 0;
            }
            token=strtok(NULL," ");
        }

Я попытался реализовать функцию strspn, как было предложено следующим образом:

        printf("Enter numbers:\n");
        fgets (str, sizeof(int)*(size+1)+size*size, stdin);
        int index;
        token=strtok(str," ");
        for(int i=0; (i<size) && (token!=NULL); i++) {
            if(sscanf(token,"%d",&numbers[i])==1){
            index=strspn(token,"0123456789");
            }if (str[index]!='\n'&&str[index]!='\0'){
                printf("Invalid number\n");
                return 0;
            }
            token=strtok(NULL," ");
        }

для ввода: 8 8a 8 программа не печатает Invalid number

1 Ответ

1 голос
/ 11 ноября 2019

Другой подход заключается в использовании спецификатора %n для итерации по строке.
%n сохраняет количество символов, обработанных при сканировании.
str + offset будет сканировать каждое целое число в строке.
Если сканирование не удается, offset должен быть индексом символа, вызывающего проблему.

#include <stdio.h>

#define SIZE 20

int main ( void) {
    char str[SIZE * SIZE] = "";//allow SIZE characters for SIZE number of integers
    int numbers[SIZE] = { 0};

    printf("Enter numbers:\n");
    fgets (str, sizeof str, stdin);
    int scanned = 0;
    int offset = 0;
    int i = 0;
    while ( i < SIZE && 1 == sscanf ( str + offset, "%d%n", &numbers[i], &scanned)) {
        i++;
        offset += scanned;
    }

    if ( '\n' != str[offset] && '\0' != str[offset] && ' ' != str[offset]) {
        if ( i < SIZE) {
            printf ( "input problem at: %s\n", str + offset);
        }
    }

    return 0;
}

Использование strspn также может работать.

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

#define SIZE 20

int main ( void) {
    char str[SIZE * 20] = "";
    int numbers[SIZE] = { 0};

    printf("Enter numbers:\n");
    fgets (str, sizeof str, stdin);
    int index = strspn ( str, "\t\r\n 0123456789");//find a non-matching character
    if ( str[index]) {//found one
        printf ( "good: %.*s\n", index, str);
        printf ( "problem: %s\n", str + index);
    }
    else {//str has only digits and whitespace
        int scanned = 0;
        int offset = 0;
        int i = 0;
        while ( i < SIZE && 1 == sscanf ( str + offset, "%d%n", &numbers[i], &scanned)) {
            printf ( "number[%d]: %d\n", i, numbers[i]);
            i++;
            offset += scanned;
        }
    }

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