从C中的文件中读取原语

时间:2010-07-06 20:21:02

标签: c file-io stream iostream

我是C新手,想要从文件中读取一些数据。

实际上,我发现很多阅读功能,fgetc,fgets等。 但我不知道哪个/组合最好用以下格式读取文件:

0 1500 100.50
1 200     9
2 150     10

我只需要将上面的每一行保存到一个包含三个数据成员的结构中。

我只需要知道这样做的最佳实践,因此我是C编程的新手。

感谢。

2 个答案:

答案 0 :(得分:5)

尝试使用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 :(得分:1)

#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之间的空格字符是必需的,以便跳过数字之间的任何空格。这在行的末尾尤其重要,必须读取换行符。
  • 大多数代码都与彻底检查错误有关。几乎每个函数调用的返回值都会被检查是否成功。此外,将已读取的字段数和字符数与预期值进行比较。
  • fscanffprintf的格式字符串在细节方面有所不同。请务必阅读相关文档。
  • 我使用fgets的组合一次读取一行,sscanf解析字段。我这样做是因为我似乎无法使用\n来匹配单个fscanf
  • 我使用GNU C编译器和标准警告标志-Wall -Wextra。这有助于避免一些容易出错的错误。

更新:我忘了检查fgets的每次调用只读一行。可能存在太长而无法放入缓冲区的行。应该检查该行总是以\n结束。