Как сканировать строку (с пробелом) и целое число в одной строке в C - PullRequest
0 голосов
/ 19 ноября 2018

У меня есть вход "ТАК ЖЕ 1".Здесь «SAME AS» - строка, а «1» - целое число.Как мне принять их обоих в качестве входных данных, если они находятся в одной строке.

Использование [^ \ n] не помогает, так как также принимает «1» как часть строки.Использование [^ 0-9] также не помогает, так как та же команда scanf должна принимать ввод как «ВЛЕВО» ИЛИ «ВПРАВО», которые не заканчиваются цифрой.

Есть ли способ объединить [^ \ n] и [^ 0-9]?Есть ли другой способ?

PS: вход не может быть изменен.

1 Ответ

0 голосов
/ 19 ноября 2018

scanf() не волнует переводы строк

До определенного момента, вы можете сделать это так:

#include <stdio.h>

int main(void)
{
    char buffer[64];

    int rc;
    int number;
    while ((rc = scanf("%63[^\n0-9]%d", buffer, &number)) != EOF)
    {
        if (rc == 0)
        {
            printf("Nothing read!\n");
            int c;
            while ((c = getchar()) != EOF && c != '\n')
                ;
        }
        else if (rc == 1)
            printf("Simple word - no number [[%s]]\n", buffer);
        else
            printf("Word and number [[%s]] %d\n", buffer, number);
    }
    return 0;
}

Это захватывает и проверяет результат scanf(). Например, учитывая файл данных:

SAME AS 1
LEFT
RIGHT

программа читает это следующим образом:

Word and number [[SAME AS ]] 1
Nothing read!
Simple word - no number [[LEFT]]
Simple word - no number [[RIGHT]]

Можно было бы добавить цикл «символическое поглощение» после отчета «слово и число». Для этого может быть лучше создать микро-функцию:

static inline void gobble(void)
{
    int c;
    while ((c = getchar()) != EOF && c != '\n')
        ;
}

Сначала добавьте в файл данных строку с номером, например:

SAME AS 1
LEFT
RIGHT
123 ANGELS

и вы получите:

Word and number [[SAME AS ]] 1
Nothing read!
Simple word - no number [[LEFT]]
Word and number [[RIGHT]] 123
Simple word - no number [[ ANGELS]]

Семейство функций scanf() почти не обращает внимания на символы новой строки или другие пробелы, кроме случаев, когда вы заставляете их делать это. Весь файл мог также находиться в одной строке или иметь каждый набор непробелов в своей собственной строке и будет производить примерно такой же вывод.

Вы заботитесь о переводе строк

Если вы хотите ввод на основе строки, лучше всего прочитать строки и затем проанализировать результат. Это также имеет то преимущество, что вы можете более последовательно сообщать об ошибках. Например:

#include <stdio.h>

int main(void)
{
    char line[4096];

    while (fgets(line, sizeof(line), stdin) != NULL)
    {
        char buffer[64];
        int number;
        int rc = sscanf(line, "%63[^\n0-9]%d", buffer, &number);
        if (rc == 0)
            printf("Nothing read! (line = [[%s]])\n", line);
        else if (rc == 1)
            printf("Simple word - no number [[%s]]\n", buffer);
        else if (rc == 2)
            printf("Word and number [[%s]] %d\n", buffer, number);
        else
            printf("sscanf() returned %d - can't happen (but did)?\n", rc);
    }
    return 0;
}

И работает на первом файле:

Word and number [[SAME AS ]] 1
Simple word - no number [[LEFT]]
Simple word - no number [[RIGHT]]

и второй файл:

Word and number [[SAME AS ]] 1
Simple word - no number [[LEFT]]
Simple word - no number [[RIGHT]]
Nothing read! (line = [[123 ANGELS
]])

Очень трудно использовать любую из функций семейства scanf() и избегать конечного пробела в данных SAME AS - если вы не воспользуетесь «двумя словами плюс число» или «одним словом плюс число» или « одно слово », для чего потребуется пример« чтение строки »(вторая программа) и несколько попыток с sscanf().

Семейство функций scanf() очень, очень, очень трудно использовать точно. Очень часто чтение строки и использование sscanf() помогает уменьшить сложность, но даже тогда она не идеальна. См. Руководство для начинающих вдали от scanf() для получения дополнительной информации по теме.

...