1.fgets描述
linux下man fgets查手册知道,fgets()会一直读到文件EOF或者一个新行。换行符("\n")会放入fgets指定缓冲区,且末尾后会加入"\0";
fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s. Reading stops after an EOF or a newline. If a newline is read , it is stored into buffer. A terminating null byte ("\0") is store after the last character in the buffer.
2.fgets, gets区别
gets()和fgets()都是可以从键盘输入字符串,遇到换行符或EOF为止。那么它们有什么区别呢?
1)gets()没有指定输入字符大小,会无限读取。但是不安全,要求程序员自行控制缓冲区大小;fgets()会要求指定输入字符大小,不会无限读取,更安全。
e.g. 假设输入的字符串长度 > s缓存长度,也不会报错,但是可能会溢出。溢出不一定会报错,要看溢出的RAM空间是否会影响到别的进程。
char s[2];
gets(s);
printf("%s", s);
e.g. 输入字符串长度不能超过指定读取的长度,而且最后一个byte会用于填充'\0'(fgets指定size的最后1个byte,而非缓存中最后1个byte才填充 '\0')。 如果超过,超过的内容会留在输入流中。
char s[2];
fget(s, sizeof(s), stdin);
printf("%s", s);
3.fgets最后一行重复问题
当最后一行为空时,fgets会重复倒数第二行数据。
e.g. fgets读取ASCII文本。
1 void read_file1()
3 FILE *fp ;
4 char *fileName = "./test.txt"; //待读取文本文件
6 if((fp = fopen(fileName, "r")) == NULL)
8 printf("file %s does not exist.\n", fileName);
9 return -1;
10 }
12 char s[256] = {0};
13 int lineNum = 0;
15 while(!feof(fp))
16 {
17 fgets(s, sizeof(s), fp);
19 printf("%d: %s\n", lineNum, s);
20 printf("len = %d\n", strlen(s));
21 printf("last char's ASCII code = %d\n", s[strlen(s) - 1]);
23 lineNum ++;
24 }
26 fclose(fp);
首先是循环结束条件,feof(fp)是检测流上的文件结束符,如果文件结束,则返回非0;如果文件未结束,则返回0。
第1行"bbb\n"读完以后,此时并不知道文件结尾,s="bbb\n\0",会继续读下一行。
第2行""(空)会读到文件结尾EOF,正常情况会将'\0'用于填入空串后,为何还会填充前面一行内容呢?
这是因为用fgets获取最后一行(空行)失败,而抓取的s数据会在检查到已经到文件结尾(循环结束条件)之前,就打印了。也就是说打印内容其实是无效的,实际上fgets并未影响到缓存s内容,也就是倒数第二行内容。
改善:将打印数据内容放到检查是否已经碰到文件末尾之后
FILE *fp;
char s[256];
while(true)
fgets(s, sizeof(s), fp);
if(feof(fp))
break;
printf("%s", s);
fclose(fp);
打印结果:
本文来自博客园,作者:明明1109,转载请注明原文链接:https://www.cnblogs.com/fortunely/p/12672934.html