我有一个文本文件,其中三个字段用逗号分隔。 我的文本文件的内容示例:12345,真正的编程新手,BS ME 要将文件加载到程序中,我使用下面的代码....我的问题是,有时代码工作,有时它不会(没有错误消息出现程序只关闭自己,不会继续)。我还观察到文本文件是空白的(没有写入任何内容)它会自动关闭并且不会继续。非常感谢您的帮助。谢谢!
int read(){
FILE *stream = NULL;
int ctr;
char linebuffer[45];
char delims[]=", ";
char *number[3];
char *token = NULL;
stream = fopen("student.txt", "rt");
if (stream == NULL) stream = fopen("student.txt", "wt");
else {
printf("\nReading the student list directory. Wait a moment please...");
while(!feof(stream)){
ctr=0;
fgets(linebuffer, 46, stream);
token = strtok(linebuffer, delims);
while(token != NULL){
number[ctr] = linebuffer;
token = strtok(NULL, delims);
ctr++;
}
recordCtr++;
}
recordCtr--;
}
fclose(stream);
}
答案 0 :(得分:2)
一旦找到,就永远不会复制token
。您无法复制linebuffer
,因为当下一行被加载时,其中的数据将被覆盖。
这一行:
number[ctr] = linebuffer;
应该引用token
来保存最近找到的令牌,但事实并非如此。它应该读起来像 1 :
strcpy(number[ctr], token);
但是你必须改变声明以确保空间:
char number[3][32];
显然,这会引入缓冲区溢出风险,如果有一个非常长的令牌则不适合。如何最好地处理这是一个练习。 :)
1 为什么临时矢量在用于存储两个数字时被称为“数字”,一个字符串(名称)超出我的范围。
答案 1 :(得分:1)
您的fgets()
调用需要指定45作为大小,或者当fgets写入NULL终止符时,您会缓冲缓冲区。这会将“delims”字符串设置为空字符串。
即使函数声明声明它返回一个int,你也不会返回任何值。
我不知道你的“struct student”的定义是什么,但是在使用strcpy()
时你可能会溢出缓冲区。你也减少了“recordCtr”。为什么?如果您无法打开文字,为什么要打开文件进行书写?为什么?如果失败,则在NULL指针上调用fclose。我怀疑这有多大帮助。
我刚注意到你没有初始化“数字”。如果第一行没有得到三个数字,那么从未初始化的指针开始strcpy()
。它可能具有NULL值,因此程序将会出现段错误。
你也有一个大小为3的数组,但是如果你读的行有超过3个以逗号分隔的字段,你将会溢出数组。
也可能有很多其他错误。
很多程序员都不会费心去做所有好的编码实践,例如检查返回值,初始化变量等等。他们经常会得到像这样的代码。如果你想成为一名优秀的程序员,那就试着养成做所有这些事情的习惯,或者至少一直考虑你是否需要。
此代码中存在许多潜在错误。如果一行超过45个字符,会发生什么?您不会删除换行符。你没有将字符串转换为数字(虽然数字[1]似乎是一个字符串数据,所以为什么要将它存储在一个名为“数字”的数组?)或检查fgets实际返回任何数据或检查你有多少数据得到。
答案 2 :(得分:1)
让买家小心。
strtok 可能会有一些边缘情况需要担心。
“一,二,三”将产生3个代币。
“one ,, three”将产生2个令牌。