user-0 提问: strtok函数问题，无法正确识别EOF

回复:
user: user-0
content: 我再上一次代码吧： #include <stdio.h> #include <stdlib.h> #include <string.h>   int sum=0;/*信息条目总数*/   typedef struct{ char number[6];/*索书号*/ char bookname[30];/*书名*/ char author[40];/*作者及译者*/ char keyword[40];/*关键字*/ char zhongtu[10];/*中图法分类号*/ char ISBN[25];/*ISBN*/ char press[30];/*出版社*/ char pubdate[10];/*出版日期*/ char times[3];/*印刷版次*/ char appendix[30];/*配给*/ char info[50];/*备注*/    }book;  book data[200];/*结构数组用于保存全部书目信息*/  int main(void) {  int i;  char temp[274]={0};   FILE* load; load=fopen("library.txt","r"); if(load==NULL){  puts("lib didn't read properly");  exit(1);  }   	while(1){ 	memset(temp,0,274); 	fgets(temp,274,load); 	if(feof(load)) break;/*在读入最后一行后，feof才做有效检验*/      strcpy(data[i].number,strtok(temp,","));   /*数据加载*/  	strcpy(data[i].bookname,strtok(NULL,",")); 	strcpy(data[i].author,strtok(NULL,",")); 	strcpy(data[i].keyword,strtok(NULL,",")); 	strcpy(data[i].zhongtu,strtok(NULL,",")); 	strcpy(data[i].ISBN,strtok(NULL,",")); 	strcpy(data[i].press,strtok(NULL,",")); 	strcpy(data[i].pubdate,strtok(NULL,",")); 	strcpy(data[i].times,strtok(NULL,",")); 	strcpy(data[i].appendix,strtok(NULL,",")); 	strcpy(data[i].info,strtok(NULL,"\n"));          printf("%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n",data[i].number,data[i].bookname,data[i].author,data[i].keyword,data[i].zhongtu,\ 	data[i].ISBN,data[i].press,data[i].pubdate,data[i].times,data[i].appendix,data[i].info);      	i++;      sum++;/*数据加载 获得总条数*/ 	} 	 fclose(load); 	  return 0; } /*main函数*/

user: user-0
content: 这个eof搞死我了  我在实际使用的时候，又产生了eof 提前结束的情况。也测试不出来原因，就正常的结束了，大神再看看吧？  代码跟上面的没有本质区别，我就上一下文件吧。估计还是文件出的问题。  1-1-05,GMAT词汇精选,俞敏洪(编著),英语-词汇-研究生,H313,978-7-80080-549-3,群言出版社,2006.1,8,光盘一张,  1-2-01,人间失格,太宰治(著)高詹灿(译),自传体-小说-日本,I313,978-7-201-07970-7,天津人民出版社,2013.3,5, ,人间失格即丧失人的资格 2-3-15,photoshop CS5 从入门到精通,新视角文化行(编著),图形软件-photoshop,TP391,978-7-115-23837-5,人民邮电出版社,2010.12,1,DVD两张,  4-1-10,中外著名枪械鉴赏图鉴,李大光(编著),手枪-世界-普及读物,E922,978-7-224-09475-6,西泠出版社,2012.1,1, ,美丽的过时 3-5-20,普通话水平测试实施纲要,国家语言文字工作委员会(编著),普通话-水平考试-自学,H102,978-7-100-03996-3,商务印书馆,2004.1,19,一张光盘,根据教育部发布《普通话水平测试管理规定制作本大纲》  莫名其妙在第四个读完之后，读第五个的时候就认为是eof了？而且data[i].number 明明值等于1-1-05,printf出来却等于1-1-05GMAT词汇精选 好奇怪啊。真的懵比，我就是照着上午的程序抄的，规模大了一点，不知道为什么又出错了。

user: user-1
content: 看看这篇：http://blog.csdn.net/ysdaniel/article/details/7954668

user: user-0
content: 还是想询问一下 空行并不算末尾对吧，不然正常的段落间的空行就无法判断了对吧？没想到竟然是这种地方的问题。

user: user-0
content: 非常感谢，顺便问一下memset(temp,0,200)是说把temp数组的两百个元素初值都设定为0的意思吧。

user: user-0
content: 引用 11 楼 qq423399099 的回复: 版主果然厉害，是多了一个空行？多了一个空行咋了？空行影响EOF吗？

user: user-1

user: user-1
content: 我猜是你的a.txt最后多了一个空行，删掉空行试试。 或者改成下面这样：判断一下读到的字符数，如果是0的话就跳出  #include <stdio.h> #include <stdlib.h> #include <string.h>  typedef struct{ char number[10]; char text[40]; char author[40]; char code[10];  }book; book data[20];  int main(void) { int i=0; char temp[200]={0}; FILE *in;  in=fopen("a.txt","r"); if(in==NULL){ printf("not open file."); exit(1); }   while(!feof(in)){	 	memset(temp, 0, 200);     fgets(temp,200,in); 	if(strlen(temp) == 0) 		break;     strcpy(data[i].number,strtok(temp,","));     strcpy(data[i].text,strtok(NULL,","));     strcpy(data[i].author,strtok(NULL,","));     strcpy(data[i].code,strtok(NULL,"\n"));     	     printf("%s\t%s\t%s\t%s\n",data[i].number,data[i].text,data[i].author,data[i].code);     i++; }        fclose(in);    return 0;	  }

user: user-0
content: 引用 3 楼 qq423399099 的回复:楼主顺便贴下文件吧 其实我就是想写一个能读以逗号为分隔符的函数，越搞问题越多。。

user: user-0
content: 测试了一下，按照ForestDB 还是不行。并不能测出EOF。  我观察之后是这样的，在我fgets我目标行之后，它还会再fgets一次，获得的数据是   所以我想到的大概是这么一个结构：  while(1) { fgets(temp,200,in); while(){  strcpy(data[i].number,strtok(temp,",")); strcpy(data[i].text,strtok(NULL,","));  strcpy(data[i].author,strtok(NULL,","));  strcpy(data[i].code,strtok(NULL,"\n"));  printf("%s\t%s\t%s\t%s\n",data[i].number,data[i].text,data[i].author,data[i].code);   i++; } break; }  现在因为我还是不太了解这个函数，所以不知道内层的while填写一个什么条件（我知道写什么，但不知道格式）。填写一个条件，让strtok的返回值等于null的时候，就终止（因为最后一次fgets的第一个值就是\n，如果判断能以\n作为分隔符，那么这个strtok的返回值就能是null，如果满足这个条件就停止就行了）。我觉得我离问题问题解决就差一点，可惜我基本功不牢。

user: user-2
content: 另外文件中有中文，所以要注意编码中可能有\x0，所以要选对的API和注意编码问题。

user: user-0
content: 引用 4 楼 ForestDB 的回复:while(!feof(in)){     fgets(temp,200,in);  把这一小段逻辑改成： while (1) {     fgets(temp, 200, in);     if (feof(in))         break; 或者直接是 while (fgets(temp, 200, in)) { 试试。  原因就是fgets读完文件最后一行后，并未到达文件结尾（可以假想EOF还为读到），这时去测试feof为假； 然后fgets再去读，才知道文件结束（读到EOF），这时feof测试才为真。我现在的想法已经很接近这个了！我马上试试。我另外把我测试遇到的问题再反馈一下。

user: user-0
content: a.txt吗？ 1-1-05,GMAT词汇精选,俞敏洪(编著),英语-词汇-研究生 1-2-01,人间失格,太宰治(著)高詹灿(译),自传体-小说-日本 2-3-15,photoshop CS5 从入门到精通,新视角文化行(编著),图形软件-photoshop 4-1-10,中外著名枪械鉴赏图鉴,李大光(编著),手枪-世界-普及读物 3-5-20,普通话水平测试实施纲要,国家语言文字工作委员会(编著),普通话-水平考试-自学

user: user-2
content: while(!feof(in)){     fgets(temp,200,in);  把这一小段逻辑改成： while (1) {     fgets(temp, 200, in);     if (feof(in))         break; 或者直接是 while (fgets(temp, 200, in)) { 试试。  原因就是fgets读完文件最后一行后，并未到达文件结尾（可以假想EOF还为读到），这时去测试feof为假； 然后fgets再去读，才知道文件结束（读到EOF），这时feof测试才为真。

user: user-1
content: 楼主顺便贴下文件吧

user: user-3
content: http://c.biancheng.net/cpp/html/2514.html

user: user-0
content: 有谁看了这篇文章能明白我改怎么改吗？学生一枚，确实需要帮助呀  http://blog.csdn.net/liuintermilan/article/details/6283705