我正在阅读.csv文件:
FILE * fPointer; = fopen(fileName, "r");
char singleLineContent[150];
while(fgets(singleLineContent, 150, fPointer))
{
/* data handling */
}
它停止在40239行读取文件。我不知道为什么。
这是整个文件。它返回-1。文件中有超过100万行。我还用这些数据写了另一个文件:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
int main()
{
printf("Type the name of a file to be read (30 character max): ");
char fileName[30];
scanf("%s", fileName);
printf("Type the name of destination file (30 character max): ");
char fileNameW[30];
scanf("%s", fileNameW);
FILE * fPointerForWriting = fopen(fileNameW, "w");
FILE * fPointer;
fPointer = fopen(fileName, "r");
int i = 1;
char singleLineContent[150];
while(fgets(singleLineContent, 150, fPointer))
{
char *token = strtok(singleLineContent, ",\n");
fprintf(fPointerForWriting, "%d", atoi(token));
token = strtok(NULL, ",\n");
fprintf(fPointerForWriting, ",%d %d\n", atoi(token), i);
if(token == NULL)
{
printf("There are no tokens\n");
return -3;
}
i++;
}
fclose(fPointerForWriting);
fclose(fPointer);
return 0;
}
它说我需要添加更多不是代码的细节。它说我需要添加更多不是代码的细节。它说我需要添加更多不是代码的细节。它说我需要添加更多不是代码的细节。它说我需要添加更多不是代码的细节。它说我需要添加更多不是代码的细节。它说我需要添加更多不是代码的细节。
答案 0 :(得分:3)
您应该更加小心地从{"id":123,"userId":116,"contentId":0}
读取文件名:如果您输入超过29个字符,stdin
可能会导致缓冲区溢出。在提示中提到的甚至30个字符太多了。使用以下格式:
scanf
这将防止潜在的未定义行为,但您应该通过测试返回值为错误情况添加适当的检查,例如文件结尾。此外,scanf("%29s", fileName);
是一个非常差的API来读取文件名,它将停在第一个空格字符处,这在目前的文件名中很常见。
读取文件名的更好解决方案是:
scanf
同样,您应该检查文件是否可以成功打开。
最后,如果您在开头读取的行数少于2,那么您的解析器将无法检测到并调用未定义的行为:
fgets(fileName, sizeof(fileName), stdin);
fileName[strcspn(fileName, "\n")] = '\0';
如果 char *token = strtok(singleLineContent, ",\n");
fprintf(fPointerForWriting, "%d", atoi(token));
token = strtok(NULL, ",\n");
fprintf(fPointerForWriting, ",%d %d\n", atoi(token), i);
if(token == NULL)
{
printf("There are no tokens\n");
return -3;
}
为token
,则NULL
会调用未定义的行为:它可能会使您的程序崩溃,退出代码为atoi(token)
。
添加这样的正确测试:
-1
答案 1 :(得分:-1)
我怀疑当OS输出缓冲区变满时程序停止,操作系统尝试写入没有名称的文件。
查看我关于使用scanf()和空格
的评论