чтение неизвестного числа целых чисел из стандартного ввода (C) - PullRequest
7 голосов
/ 04 февраля 2010

Мне нужно прочитать входной файл, например:

1
19 20 41 23
2
41 52 43
3
90 91 941
4
512
5

6
51 61

Каждая нечетная строка является целым числом.Каждая четная строка представляет собой неизвестное число целых чисел.

Это очень легко в C ++

while( cin >> k ){
............
}

Я не так привык к C, поэтому я не мог сделать это в C. Любые способысделать это?

Ответы [ 6 ]

12 голосов
/ 04 февраля 2010

Запуск вашего входного файла через:

#include <stdio.h>

int main() {
        int k;
        while (scanf("%d", &k) == 1) {
                printf("read number: %d\n", k);
        }
        return 0;
}

Результат:

read number: 1
read number: 19
read number: 20
read number: 41
read number: 23
read number: 2
read number: 41
read number: 52
read number: 43
read number: 3
read number: 90
read number: 91
read number: 941
read number: 4
read number: 512
read number: 5
read number: 6
read number: 51
read number: 61

Это аналог кода C, на который вы ссылаетесь в исходном вопросе.

9 голосов
/ 04 февраля 2010

Я бы сделал так, чтобы разбить его на две операции: прочитать строку, а затем прочитать целые числа в этой строке. Вот ленивая реализация, использующая стандартную библиотеку C:

char line[1024], *p, *e;
long v;
while (fgets(line, sizeof(line), stdin)) {
    p = line;
    for (p = line; ; p = e) {
        v = strtol(p, &e, 10);
        if (p == e)
            break;
        // process v here
    }
}
3 голосов
/ 04 февраля 2010

Я бы разбил программу на разные задачи.

Первый шаг - это возможность прочитать пару строк, первая строка, которая сообщает количество прочитанных чисел, а затем вторая строка.читать реальные цифры.Для этого может быть полезна функция с именем вроде read_set.Он должен быть в состоянии возвратить прочитанные числа и сигнал конца файла, а также ошибки.Для этого мы можем определить структуру данных, такую ​​как:

struct numbers {
    long *data; /* or choose a type depending upon your needs */
    size_t len;
};

, а затем мы можем объявить нашу функцию с прототипом:

int read_set(FILE *fp, struct numbers *num);

Функция будет выделять память для num->dataи установите num->len на правильное значение.В случае успеха возвращается 0, а в противном случае - набор условий ошибки.Мы могли бы проявить фантазию и использовать enum для возврата статусов позже.А теперь давайте предположим, что 0 = успех, 1 = конец файла, а все остальное является ошибкой.

Затем вызывающий вызов вызывает read_set() в цикле:

struct numbers numbers;
int status;
while ((status = read_set(fp, &numbers)) == 0) {
    /* process numbers->data, and then free it */
}
if (status == 1) {
    /* hit end of file, everything is OK */
} else {
    /* handle error */
}

ДляРеализация read_set(): она должна прочитать две строки.Существует множество реализаций чтения полной строки в C , поэтому вы можете использовать любую из них и сначала прочитать строку, затем sscanf() / strtoul() для одного числа (проверьте возвращаемое значение!).Если у вас есть количество чисел, n, вы можете прочитать следующую строку в памяти и выполнить:

num->data = malloc(n * sizeof *num->data);
num->len = n;

Затем вы можете повторно вызывать sscanf() или strtol() для сохранения номеров в num->data.Вы должны поставить галочки, чтобы убедиться, что в этой строке точно находятся n числа.

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

1 голос
/ 04 февраля 2010

Я бы сделал одно из:

  • fgetc (), чтобы читать отдельные символы и анализировать их самостоятельно (накапливать цифры до тех пор, пока вы не нажмете пробел, и у вас не получится целое число для преобразования с помощью atoi (); если пробел является новой строкой, то он завершает список целых чисел )

  • fgets () для чтения строки за раз, а затем синтаксического анализа строки (снова ищите пробел, разделяющий значения), которую она возвращает.

0 голосов
/ 03 марта 2017

Я придумал такое решение:

while(scanf("%d%c", &n, &ch)!=EOF)
{
    if(ch=='\n') break;
    /* rest of your code */
}
0 голосов
/ 04 февраля 2010

посмотрите на getc (3) или scanf (3)

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