Принятие любого количества входных данных из функции scanf

Я пытаюсь прочитать неизвестное количество входных данных, используя функцию scanf.

int a[100];
int i = 0;

while((scanf("%d", &a[i])) != '\n')
 i++;

// Next part of the code

Но эта функция не переходит к следующей части кода, похоже, что существует бесконечный цикл while.

Как решить эту логическую ошибку? Существуют ли другие альтернативы scanf, например sscanf, для чтения целых чисел в массив?


person user2147954    schedule 08.03.2013    source источник
comment
Как вы хотите отметить конец ввода?   -  person Avidan Borisov    schedule 08.03.2013
comment
Предположим, пользователь начинает вводить список чисел, скажем, 10 пробел 20 пробел 30, и после того, как он закончил ввод, он должен нажать клавишу ввода, чтобы выйти из цикла.   -  person user2147954    schedule 08.03.2013
comment
Возвращаемое значение scanf — это ‹b›количество входных элементов, успешно сопоставленных‹/b› и назначенных, которое может быть меньше, чем предусмотрено, или даже равно нулю в случае неудачи раннего сопоставления. Так что сравнение с \\n некорректно.   -  person uba    schedule 08.03.2013
comment
Потому что это getchar, который возвращает следующий символ из стандартного ввода, а не scanf   -  person uba    schedule 08.03.2013


Ответы (6)


scanf возвращает количество успешно сопоставленных и назначенных элементов ввода, поэтому целесообразно сделать следующее:

while(scanf(...) == 1)

Теперь вы хотите иметь возможность читать несколько чисел, каждое из которых определено в новой строке. Тогда вы можете просто сделать это:

int array[100];
int i = 0;

while(i < 100 && scanf("%d\n", &array[i]) == 1)
    i++;

обратите внимание, что это чтение остановится только в том случае, если введен неверный ввод (например, буква q) или когда вы введете контрольный код конца ввода, который равен Ctrl+Z (в Windows) или Ctrl+D (в Mac, Linux, Unix).

person LihO    schedule 08.03.2013
comment
Обратите внимание, что завершающий \n в строке формата scanf() является катастрофой пользовательского интерфейса, если пользователи будут вводить ввод. Ввод первого числа не заканчивается, пока вы не наберете что-то (предположительно второе число), которое не является пробелом. Кроме того, новая строка в строке формата соответствует любому пробелу — пробелу или табуляции, а также новым строкам; он решительно не требует новой строки. И, наконец, последний гвоздь в гроб на данный момент, спецификации числового преобразования, такие как %d, автоматически пропускают (начальные) пробелы. Только %c, %[…] (наборы сканирования) и %n не пропускают пробелы. - person Jonathan Leffler; 03.05.2017
comment
Рекомендация: удалите \n из строки формата. Код будет работать лучше, когда его печатает человек. (Для пользователя не будет очевидно, что существует проблема, поскольку между вводимыми числами нет обратной связи. Так что в этом примере вам сойдет с рук. В других контекстах возникнут проблемы, требующие от пользователя предвидения — знания введите следующий.) - person Jonathan Leffler; 03.05.2017

Возвращаемое значение scanf — это количество элементов ввода, успешно сопоставленных и назначенных, поэтому попробуйте завершить его при обнаружении нечислового ввода:

while (i < 100 && (scanf("%d", &a[i])) == 1) { i++; }
person Klas Lindbäck    schedule 08.03.2013
comment
@ user2147954: Потому что чтение продолжается до тех пор, пока не будет введен неверный ввод или EOF. Смотрите мой ответ. - person LihO; 08.03.2013

Сначала замените "%d" на " %d", чтобы избежать проблем с новой строкой.

во-вторых, если ваш ввод содержит нечисловой ввод, тогда ваш цикл while войдет в бесконечный цикл. поэтому вы должны проверить свой ввод, если это числовой ввод

person MOHAMED    schedule 08.03.2013

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

Можешь попробовать

   while((i<10) && (scanf("%d",a+i)==1)) i++;

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

   while (fgets(mybuf, ALLOCATED_LENGTH-1, stdin)) {
        char *p = mybuf;
        if (*p=='\n') break; // or a better function to test for empty line
        while (custom_scan_next_integer(&p)) i++;
   }

где custom_scan_next_integer изменяет указатель p для пересылки нужного количества символов.

person Aki Suihkonen    schedule 08.03.2013
comment
Это работает, но отсутствует весь смысл чтения неизвестного количества входных данных в массив. магическое число 10 не хорошо. Дело в том, что я не знаю, сколько цифр пользователь введет, прежде чем нажать клавишу ввода. - person user2147954; 08.03.2013

Ты хочешь сделать

char discard;

while(i < 100 && (scanf("%d%1[^\n]s", &arr[i], &discard)) == 2)
 i++;

продолжать получать ввод до новой строки.

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

person Avidan Borisov    schedule 08.03.2013
comment
Будет ли это работать? Я ожидаю, что между всеми числами будет пробел. - person ams; 08.03.2013

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

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

int main() { 
    int i=0, j=0; 
    int arr[10000]; 
    char temp; 
    do { 
       scanf("%d%c", &arr[i], &temp); 
       i++; 
    } while(temp != '\n'); 

    for(j=0; j<i; j++) { 
       printf("%d ", arr[j]); 
    } 

    return 0; 
}

этот код принадлежит Абхишеку Бхаттачарье (из Quora) (первый ответ)

person AHTI    schedule 26.02.2021
comment
Пожалуйста, дайте ссылку на страницу Quora, с которой вы получили код. - person Null; 26.02.2021