user-0 提问: 关于 fegts() 丢每行 首个字符的问题

回复:
user: user-1
content: 不要使用 while (条件) 更不要使用 while (组合条件) 要使用 while (1) {  if (条件1) break;  //...  if (条件2) continue;  //...  if (条件3) return;  //... } 因为前两种写法在语言表达意思的层面上有二义性，只有第三种才忠实反映了程序流的实际情况。 典型如： 下面两段的语义都是当文件未结束时读字符 while (!feof(f)) {  a=fgetc(f);  //...  b=fgetc(f);//可能此时已经feof了！  //... } 而这样写就没有问题： while (1) {  a=fgetc(f);  if (feof(f)) break;  //...  b=fgetc(f);  if (feof(f)) break;  //... } 类似的例子还可以举很多。

user: user-1
content: 仅供参考：#include <stdio.h> #include <string.h> #define MAXLEN 1000 char ln[MAXLEN]; FILE *f; int i,z; int b,n,L; int main(int argc,char **argv) {     if (argc<2) {         printf("Usage:%s fullpathfilename.ext\nget total blank/non-blank/total linenumbers.\n",argv[0]);         return 1;     }     f=fopen(argv[1],"r");     if (NULL==f) {         printf("Can not open file [%s]!\n",argv[1]);         return 2;     }     z=0;     b=0;     n=0;     L=0;     while (1) {         if (NULL==fgets(ln,MAXLEN,f)) break;         L=strlen(ln);         if ('\n'==ln[L-1]) {             if (0==z) {                 for (i=0;i<L-1;i++) {                     if (!(' '==ln[i] || '\t'==ln[i])) break;                 }                 if (i<L-1) z=1;//当前行不是空行             }             if (0==z) b++; else n++;             z=0;         } else {             if (0==z) {                 for (i=0;i<L;i++) {                     if (!(' '==ln[i] || '\t'==ln[i])) break;                 }                 if (i<L) z=1;//当前行不是空行             }         }     }     fclose(f);     if (L>0 && '\n'!=ln[L-1]) {         if (0==z) b++; else n++;//最后一行末尾无'\n'也计算     }     printf("File:[%s] total blank/non-blank/total linenumbers is %d/%d/%d\n",argv[1],b,n,b+n);     return 0; }

user: user-1
content: fgetc取走的字符你啥时候保存到buffer中呢？

user: user-0
content: 引用 7 楼 mymtom 的回复:这不科学啊，楼主上代码  while( fgetc( tempFp ) != EOF ) { fgetpos( tempFp, &pos_here);  fgets( buffer, 256, tempFp );  robot_string = buffer;  memset( buffer, 0, 256 );  if( robot_string.find( "moveRobot" ) == robot_string.npos || robot_string.find( "void" ) != robot_string.npos )  { fprintf( file->FP_fp, "%s\n", robot_string.c_str() ); }  else { break; } }

user: user-0
content: 引用 6 楼 zhao4zhong1 的回复:将对fgetc的调用删掉！while (1) {     fgetpos( tempFp, &pos_here);      if (NULL==fgets( buffer, 256, tempFp )) break;      robot_string = buffer;      memset( buffer, 0, 256 );      if ( robot_string.find( "moveRobot" ) == robot_string.npos      ||  robot_string.find( "void" )      != robot_string.npos ) {         fprintf( file->FP_fp, "%s\n", robot_string.c_str() );     } else {         break;     } }     为什么 不直接调用呢，能简单解释下原因吗？ 谢谢

user: user-2
content: 这不科学啊，楼主上代码

user: user-1
content: 将对fgetc的调用删掉！while (1) {     fgetpos( tempFp, &pos_here);      if (NULL==fgets( buffer, 256, tempFp )) break;      robot_string = buffer;      memset( buffer, 0, 256 );      if ( robot_string.find( "moveRobot" ) == robot_string.npos      ||  robot_string.find( "void" )      != robot_string.npos ) {         fprintf( file->FP_fp, "%s\n", robot_string.c_str() );     } else {         break;     } }

user: user-0
content: 引用 3 楼 turingo 的回复:fgets函数从文件结构体指针stream中读取数据，每次读取一行。读取的数据保存在buf指向的字符数组中，每次最多读取bufsize-1个字符（第bufsize个字符赋'\0'），如果文件中的该行，不足bufsize个字符，则读完该行就结束。如若该行（包括最后一个换行符）的字符数超过bufsize-1，则fgets只返回一个不完整的行，但是，缓冲区总是以NULL字符结尾，对fgets的下一次调用会继续读该行。函数成功将返回buf，失败或读到文件结尾返回NULL。因此我们不能直接通过fgets的返回值来判断函数是否是出错而终止的，应该借助feof函数或者ferror函数来判断。  仔细阅读上面内容，看看问题在哪，另外也可以看看ferror的情况。  嗯，设置断点看到读到 buffer[256] 里面的就是 丢失之后的，我试试看 ferror的情况

user: user-0
content: 引用 2 楼 q3733353520 的回复:请贴代码  while( fgetc( tempFp ) != EOF ) 		{ 			fgetpos( tempFp, &pos_here);  			fgets( buffer, 256, tempFp );  			robot_string = buffer;  			memset( buffer, 0, 256 );  			if( robot_string.find( "moveRobot" ) == robot_string.npos || 				robot_string.find( "void" ) != robot_string.npos )  			{ 				fprintf( file->FP_fp, "%s\n", robot_string.c_str() ); 			}  			else 			{ 				break; 			} 		}

user: user-3
content: fgets函数从文件结构体指针stream中读取数据，每次读取一行。读取的数据保存在buf指向的字符数组中，每次最多读取bufsize-1个字符（第bufsize个字符赋'\0'），如果文件中的该行，不足bufsize个字符，则读完该行就结束。如若该行（包括最后一个换行符）的字符数超过bufsize-1，则fgets只返回一个不完整的行，但是，缓冲区总是以NULL字符结尾，对fgets的下一次调用会继续读该行。函数成功将返回buf，失败或读到文件结尾返回NULL。因此我们不能直接通过fgets的返回值来判断函数是否是出错而终止的，应该借助feof函数或者ferror函数来判断。  仔细阅读上面内容，看看问题在哪，另外也可以看看ferror的情况。

user: user-4
content: 请贴代码

user: user-0
content: 不是所有行的 首个字符丢失，只是某些行的

user: user-0
content: 引用 6 楼 zhao4zhong1 的回复:将对fgetc的调用删掉！while (1) {     fgetpos( tempFp, &pos_here);      if (NULL==fgets( buffer, 256, tempFp )) break;      robot_string = buffer;      memset( buffer, 0, 256 );      if ( robot_string.find( "moveRobot" ) == robot_string.npos      ||  robot_string.find( "void" )      != robot_string.npos ) {         fprintf( file->FP_fp, "%s\n", robot_string.c_str() );     } else {         break;     } }    谢谢解答，很详细，已经解决了

user: user-0
content: 引用 15 楼 mymtom 的回复: while (fgets(buffer, 256, tempFp) != NULL) {     // 这句有什么用？ fgetpos(tempFp, &pos_here);        // fgets(buffer, 256, tempFp);      robot_string = buffer;      // 这句有什么用？memset(buffer, 0, 256);        if (robot_string.find("moveRobot") == robot_string.npos ||         robot_string.find("void") != robot_string.npos)     {         fprintf(file->FP_fp, "%s\n", robot_string.c_str());     }      else {         break;     } }   fgetpos 这句 是个 后面 再 读取用到的。 这个清空多余吗

user: user-2
content: while (fgets(buffer, 256, tempFp) != NULL) {     // 这句有什么用？ fgetpos(tempFp, &pos_here);      // fgets(buffer, 256, tempFp);      robot_string = buffer;      // 这句有什么用？memset(buffer, 0, 256);      if (robot_string.find("moveRobot") == robot_string.npos ||         robot_string.find("void") != robot_string.npos)     {         fprintf(file->FP_fp, "%s\n", robot_string.c_str());     }      else {         break;     } }