1

我有一个由逗号分隔的三个字段的文本文件。我的文本文件内容示例: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);
}    
4

3 回答 3

2

token一旦你找到它,你就永远不会复制它。您不能复制linebuffer,因为其中的数据将在下一行加载时被覆盖。

这一行:

number[ctr] = linebuffer;

应该参考token保存最近找到的令牌,但它没有。它可能应该读为1

strcpy(number[ctr], token);

但是您必须更改声明以确保有空间:

char number[3][32];

显然,这会引入缓冲区溢出风险,如果有一个很长的令牌,它将不适合。如何最好地处理剩下的作为练习。:)

1为什么临时向量在用于存储两个数字和一个字符串(名称)时称为“数字”,这超出了我的理解。

于 2010-12-02T13:48:37.380 回答
1

让买家小心。

strtok可能需要担心一些边缘情况。

"one,two,three"将产生 3 个令牌。

"one,,three"将产生 2 个令牌。

于 2010-12-02T14:16:49.767 回答
1

您的fgets()调用需要将 45 指定为大小,否则当 fgets 写入 NULL 终止符时,您会溢出缓冲区。这会将“delims”字符串设置为空字符串。

此外,即使函数声明声明它返回一个 int,您也没有返回任何值。

我不知道你的“struct student”的定义是什么,但是你在使用strcpy(). 你也减少“recordCtr”。为什么?如果无法打开文件进行写入,为什么要打开文件进行写入?为什么?如果这也失败了,您可以在 NULL 指针上调用 fclose。我怀疑这有多大帮助。

我刚刚注意到您没有初始化“数字”。如果您在第一行没有得到三个数字,那么您将strcpy()使用未初始化的指针。它可能有一个 NULL 值,所以程序会出现段错误。

你也有一个大小为 3 的数组,但如果你读取的行有超过 3 个逗号分隔的字段,你将溢出数组。

可能还有许多其他错误。

很多程序员都懒得去做所有好的编码实践,比如检查返回值、初始化变量等等。他们经常会得到这样的代码。如果你想成为一个真正优秀的程序员,试着养成做所有这些事情的习惯,或者至少总是考虑你是否需要这样做。

这段代码中有很多潜在的错误。如果一行超过 45 个字符会怎样?您不会删除换行符。您不会将字符串转换为数字(尽管 number[1] 似乎是一个字符串数据,那么为什么将其存储在一个名为“numbers”的数组中?)或检查 fgets 是否实际返回任何数据或检查您有多少数据得到。

于 2010-12-02T13:55:24.793 回答