C语言 如何使用 fgets 逐行读取文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/41902471/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to use fgets to read a file line by line
提问by Renix
I'm new at programming so there are some basics and maybe common sense that I don't know. I have a question about how to use fgets right. Based on the explanation of fgets, it seems that fgets should stop whenever it reads n-1 characters, hit the EOF or hit a newline character. For example, I create a text file like below:
我是编程新手,所以有一些我不知道的基础知识和常识。我有一个关于如何正确使用 fgets 的问题。根据 fgets 的解释,似乎 fgets 应该在读取 n-1 个字符、遇到 EOF 或遇到换行符时停止。例如,我创建了一个如下所示的文本文件:
red 100
yellow 400
blue 300
green 500
purple 1000
...
The color and the integer is separated by a tab. When I create this text file, I need to hit enter at the end of each line to start a new line. In this case, hitting enter equals to add a newline character, '\n', is that right?
颜色和整数由制表符分隔。创建此文本文件时,我需要在每行末尾按 Enter 以开始新行。在这种情况下,按回车等于添加一个换行符 '\n',对吗?
If it is right that there is a '\n' at the end of each line, I run the fgets code as below:
如果每行末尾有一个 '\n' 是正确的,我运行 fgets 代码如下:
fgets(string, 100, fp);
Since the characters contain in each line is much less than 100, the fgets should hit the newline character before reach the maxlength limit and it should stop and return a NULL. Is that correct?
由于每行包含的字符远小于 100,因此 fget 应该在达到 maxlength 限制之前命中换行符,并且应该停止并返回 NULL。那是对的吗?
If my understanding above are not right, there is no '\n' at the end of each line, or fgets does not stop at the end of each line, what is the number of maxlength (i.e., the N in the fgets(string, N, stream) function) should I pick to make sure that the file input properly due to my ultimate goal is to parsing each line and store each line into a structure. By the way, there are 100 lines in the file.
如果我上面的理解不对,每行末尾没有'\n',或者fgets没有停在每行末尾,maxlength的个数是多少(即fgets(string)中的N , N, stream) 函数)我应该选择以确保正确输入文件,因为我的最终目标是解析每一行并将每一行存储到一个结构中。顺便说一下,文件中有 100 行。
回答by Sayed Sohan
#include <stdio.h>
int main()
{
char str[150],str2[100][150];
int i=0,j=0,value[100];
FILE* fp;
fp = fopen("file.txt", "r");
while (fgets(str,150, fp)) {
i++;
printf("%3d: %s\n", i, str);
/** if you want to split value and string*/
sscanf(str,"%s %d",&str2[j],&value[j]);
printf("%d %s\n",value[j],str2[j]);
j++;
}
fclose(fp);
return 0;
}
回答by Alec Missine
// hello.c
//
// Usage:
//
// gcc -Wall hello.c && ./a.out /tmp/somefile.txt
#include <stdlib.h> // for perror, ...
#include <stdio.h> // for printf, ...
#include <assert.h> // for assert
#include <sys/time.h> // for gettimeofday
static inline long long int nowUs () {
long long int now;
struct timeval timer_us;
if (gettimeofday(&timer_us, NULL) == 0) {
now = ((long long int) timer_us.tv_sec) * 1000000ll +
(long long int) timer_us.tv_usec;
}
else now = -1ll;
return now;
}
int main (const int argc, const char * argv[]) {
assert(2 == argc);
long long int started = nowUs();
size_t count = 0;
char msg[128], * fgets_rv;
FILE * fp = fopen(argv[1], "r");
while ((fgets_rv = fgets(msg, sizeof(msg), fp))) {
assert(fgets_rv == msg);
count++;
}
if (ferror(fp))
perror(argv[1]);
else if (feof(fp)) {
printf("Read %zu lines of file '%s' in %lldμs\n",
count, argv[1], nowUs() - started);
}
else {
printf("UNEXPECTED\n");
}
fclose(fp);
return 0;
}
Sample output:
示例输出:
alec@mba ~/process/sandbox $ gcc -Wall hello.c && ./a.out /tmp/bigfile.t02
Read 100000 lines of file '/tmp/bigfile.t02' in 16521μs
回答by Teja
fp = fopen("sample.txt", "r");
while (1) {
if (fgets(line,150, fp) == NULL) break;
i++;
printf("%3d: %s", i, line);
}
printf("%d\n",i);

