C线读数突然停止

时间:2015-06-04 19:09:37

标签: c csv pointers

我正在阅读.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;
}

它说我需要添加更多不是代码的细节。它说我需要添加更多不是代码的细节。它说我需要添加更多不是代码的细节。它说我需要添加更多不是代码的细节。它说我需要添加更多不是代码的细节。它说我需要添加更多不是代码的细节。它说我需要添加更多不是代码的细节。

2 个答案:

答案 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()和空格

的评论