【发布时间】:2011-03-12 12:29:24
【问题描述】:
我是 C 新手,想从文件中读取一些数据。
其实我发现很多阅读函数,fgetc,fgets等。 但我不知道哪种/组合最适合读取以下格式的文件:
0 1500 100.50
1 200 9
2 150 10
我只需要将上面的每一行保存到一个包含三个数据成员的结构中。
我只需要知道这样做的最佳实践,因此我是 C 编程新手。
谢谢。
【问题讨论】:
我是 C 新手,想从文件中读取一些数据。
其实我发现很多阅读函数,fgetc,fgets等。 但我不知道哪种/组合最适合读取以下格式的文件:
0 1500 100.50
1 200 9
2 150 10
我只需要将上面的每一行保存到一个包含三个数据成员的结构中。
我只需要知道这样做的最佳实践,因此我是 C 编程新手。
谢谢。
【问题讨论】:
尝试使用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 返回的内容。
【讨论】:
fscanf,但我更喜欢这个建议。
#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 的组合来解析字段。我这样做是因为我似乎无法使用 fscanf 匹配单个 \n。-Wall -Wextra 的GNU C 编译器。这有助于避免一些简单的错误。更新:我忘记检查fgets 的每次调用是否准确读取一行。可能有行太长而无法放入缓冲区。应检查该行是否始终以 \n 结尾。
【讨论】: