2010-03-28 165 views
2

我想从一个文件中读取新字符串中的每个字符串的字符串,但我认为它读取一次换行符而不是一个字符串,我不知道为什么。如果我要以错误的方式阅读字符串,请纠正我。使用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 

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

编辑1:我知道它停在一个换行符但仍然读取它。我想知道为什么它不会在第三个字符串期间读取它,并将其传输到第四个字符串,而不是将第四个字符串作为源的第四行,但它只发生一次。 该文件的方式

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

回答

3

如前所述,如果有足够的空间缓冲,然后fgets()读取数据包括换行到缓冲区和空终止该线。如果在通过换行符之前缓冲区中没有足够的空间,则fgets()会将其所能够容纳的内容(缓冲区的长度减去一个字节)复制,null将终止该字符串。库在下一次迭代中继续从fgets()停止读取。

请勿混淆长度小于2个字节的缓冲区。

请注意,gets()删除换行符(但不保护缓冲区溢出,所以不要使用它)。如果事情按照当前计划进行,gets()将从C标准的下一个版本中删除;它会从C库中移除很长一段时间(它只会成为一个非标准或者不符合标准的可用于滥用的附加功能)。

你的代码应该检查每个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的地方/ while循环;但是它们并不经常使用。

+0

哇,谢谢你的第二部分,它摆脱了我的第二个问题:一个空的额外的结构。很难找到一个循环来从文件中获取字符串的例子(或者我可能看起来不正确,尽管我一直在尝试很长时间)。 – Ivan 2010-03-28 03:06:22

0

的与fgets函数读取换行符字符作为读取字符串的一部分,此格式。

description of fgets

的与fgets()函数将读取流的字节到阵列指向S,直到n-1个字节被读入,或换行被读并转移至S,或遇到文件结束条件。该字符串然后以空字节结束。

4

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

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

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

哪里str是为你从文件中读取的数据字符串,lengthsize_t类型。

要回答对问题的编辑:第三次阅读期间不读取换行符的原因是因为您没有阅读足够的字符。您给fgets限制为12个字符,这意味着它最多可以读取最多11个字符,因为它必须将空终止符添加到最后。

您阅读的行长度为11个字符之前换行。请注意,是在该行的后面加上一个空格,当你将它输出:

Kood=223456iatb i=1 
      ^
0

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

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++; 
}