使用fgets从C中的文件中读取字符串

我试图从一个文件中读取字符串,该文件在新行上包含每个字符串,但我认为它只读取一行换行符而不是字符串,我不知道为什么。 如果我要以错误的方式阅读字符串,请纠正我。

i=0; F1 = fopen("alg.txt", "r"); F2 = fopen("tul.txt", "w"); if(!feof(F1)) { do{ //start scanning file fgets(inimene[i].Enimi, 20, F1); fgets(inimene[i].Pnimi, 20, F1); fgets(inimene[i].Kood, 12, F1); printf("i=%d\nEnimi=%s\nPnimi=%s\nKaad=%s",i,inimene[i].Enimi,inimene[i].Pnimi,inimene[i].Kood); i++;} while(!feof(F1));}; /*finish getting structs*/ 

printf是让我看到什么是什么,这是结果

 i=0 Enimi=peter Pnimi=pupkin Kood=223456iatb i=1 Enimi= Pnimi=masha Kaad=gubkina i=2 Enimi=234567iasb Pnimi=sasha Kood=dudkina 

正如您在第一个结构读取后所看到的那样,有一个空白(换行符?)onct然后一切都被移动了。 我想我可以读取一个虚拟的字符串来吸收额外的空白,然后什么都不会移动,但这并不能帮助我理解问题并避免将来使用。

编辑1:我知道它停在换行符但仍然读取它。 我想知道为什么它不会在第三个字符串中读取它并转移到第四个字符串而不是将第四个字符串作为源的第四行但它只发生一次。 顺便说一下,文件的格式是这样的

 peter pupkin 223456iatb masha gubkina 234567iasb sasha dudkina 123456iasb 

如前所述,如果缓冲区中有足够的空间,则fgets()将包含换行符的数据读入缓冲区,null终止该行。 如果在遇到换行符之前缓冲区中没有足够的空间, fgets()复制它的内容(缓冲区的长度减去一个字节),null将终止字符串。 库继续读取fgets()在下一次迭代时停止的位置。

不要乱用长度小于2个字节的缓冲区。

请注意, gets()删除换行符(但不保护您免受缓冲区溢出的影响,因此请勿使用它)。 如果事情按照目前的计划进行,则gets()将从下一版C标准中删除; 从C库中删除它将会很长一段时间(它将成为非标准 – 或标准 – 可用于滥用的附加function)。

您的代码应该检查每个fgets()函数调用:

 while (fgets(inimene[i].Enimi, 20, F1) != 0 && fgets(inimene[i].Pnimi, 20, F1) != 0 && fgets(inimene[i].Kood, 12, F1) != 0) { printf("i=%d\nEnimi=%s\nPnimi=%s\nKaad=%s", i, inimene[i].Enimi, inimene[i].Pnimi, inimene[i].Kood); i++; } 

有/ do循环的地方; 但是,它们并不经常使用。

fgets在读取换行符时停止读取,但换行符被视为有效字符并包含在返回的字符串中。

如果你想删除它,你需要自己修剪它:

 length = strlen(str); if (str[length - 1] == '\n') str[length - 1] = '\0'; 

其中str是从文件中读取数据的字符串, length的类型为size_t

回答问题的编辑:在第三次阅读期间未读取换行的原因是因为您没有阅读足够的字符。 你给fgets限制了12个字符,这意味着它实际上最多可以读取11个字符,因为它必须将null终止符添加到结尾。

您读取的行在换行符之前的长度为11个字符。 请注意,输出时该行末尾有一个空格:

 Kood=223456iatb i=1 ^ 

fgets函数读取换行符char作为字符串读取的一部分。

从fgets的描述 :

fgets()函数必须从流中读取字节到s指向的数组,直到读取n-1个字节,或者读取换行符并将其传送给s ,或者遇到文件结束条件。 然后以空字节终止该字符串。

如果Enimi / Pnimi / Kood是数组而不是指针:

 while( fgets(inimene[i].Enimi,sizeof inimene[i].Enimi,F1) && fgets(inimene[i].Pnimi,sizeof inimene[i].Pnimi,F1) && fgets(inimene[i].Kood,sizeof inimene[i].Kood,F1) ) { if( strchr(inimene[i].Enimi,'\n') ) *strchr(inimene[i].Enimi,'\n')=0; if( strchr(inimene[i].Pnimi,'\n') ) *strchr(inimene[i].Pnimi,'\n')=0; if( strchr(inimene[i].Kood,'\n') ) *strchr(inimene[i].Kood,'\n')=0; printf("i=%d\nEnimi=%s\nPnimi=%s\nKaad=%s", i, inimene[i].Enimi, inimene[i].Pnimi,inimene[i].Kood); i++; }