чтение примитивов из файла в C - PullRequest
0 голосов
/ 07 июля 2010

Я новичок в C и хочу прочитать некоторые данные из файла.

На самом деле я нахожу много функций чтения, fgetc, fgets и т. Д. Но я не знаю, какая комбинация лучше всего подходит для чтения файла в следующем формате:

0 1500 100.50
1 200     9
2 150     10

Мне просто нужно сохранить каждую строку выше в структуре с тремя членами данных.

Мне просто нужно знать лучшие практики для этого, поэтому я новичок в программировании на Си.

Спасибо.

Ответы [ 2 ]

5 голосов
/ 07 июля 2010

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

FILE* f = fopen("filename.txt", "r");
if (f) { 
    char linebuff[1024];
    char* line = fgets(linebuff, 1024, f);
    while (line != NULL) {
        int first, second;
        float third;
        if (sscanf(line, "%d %d %g", &first, &second, &third) == 3) {
            // do something with them.. 
        } else {
            // handle the case where it was not matched.
        }
        line = fgets(linebuff, 1024, f);
    }
    fclose(f);
}

В этом могут быть ошибки, но это просто пример того, как вы можете использовать функции. Обязательно проверьте, что возвращает sscanf.

1 голос
/ 07 июля 2010
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static void
read_file(const char *fname)
{
    FILE *f;
    char line[1024];
    int lineno, int1, int2, nbytes;
    double dbl;


    if ((f = fopen(fname, "r")) == NULL) {
        perror("fopen");
        exit(EXIT_FAILURE);
    }

    for (lineno = 1; fgets(line, sizeof line, f) != NULL; lineno++) {

        int fields = sscanf(line, " %d %d %lg %n", &int1, &int2, &dbl, &nbytes);
        if (fields != 3 || (size_t) nbytes != strlen(line)) {
            fprintf(stderr, "E: %s:%d: badly formatted data\n", fname, lineno);
            exit(EXIT_FAILURE);
        }

        /* do something with the numbers */
        fprintf(stdout, "number one is %d, number two is %d, number three is %f\n", int1, int2, dbl);
    }

    if (fclose(f) == EOF) {
        perror("fclose");
        exit(EXIT_FAILURE);
    }
}

int main(void)
{
        read_file("filename.txt");
        return 0;
}

Некоторые примечания к коду:

  • Функцию fscanf довольно сложно использовать.Мне пришлось немного поэкспериментировать, пока я не понял это правильно.Пробелы между %d и %lg необходимы для пропуска любого пробела между числами.Это особенно важно в конце строки, где символ новой строки должен быть прочитан.
  • Большая часть кода связана с тщательной проверкой ошибок.Почти каждое возвращаемое значение вызова функции проверяется, успешно оно или нет.Кроме того, количество полей и количество прочитанных символов сравниваются с ожидаемыми значениями.
  • Строки формата для fscanf и fprintf отличаются тонкими деталями.Обязательно прочитайте для них документацию.
  • Я использовал комбинацию fgets для чтения по одной строке за раз и sscanf для разбора полей.Я сделал это, потому что мне казалось невозможным сопоставить один \n с использованием fscanf.
  • Я использовал компилятор GNU C со стандартными флагами предупреждений -Wall -Wextra.Это помогло избежать некоторых простых ошибок.

Обновление: Я забыл проверить, что каждый вызов fgets читает ровно одну строку.Там могут быть строки, которые слишком длинные, чтобы поместиться в буфер.Следует убедиться, что строка всегда заканчивается \n.

...