Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
分段错误,解析,C_C_Parsing_Csv - Fatal编程技术网

分段错误,解析,C

分段错误,解析,C,c,parsing,csv,C,Parsing,Csv,我正在编写一个c文件,它从.csv文件中获取信息,解析它,然后删除我解析的任何内容。我遇到的问题是,在它穿过.csv文件的一行之后,我得到了一个分段错误。我听说我可以使用GDB来帮助解决这个问题,但我不知道如何使用它。这是我的.c文件 void parser(int argc, char ** argv) { FILE * songList; char * theString; char * theToken; char songs[ROOM_STRING_LENGTH]; char artis

我正在编写一个c文件,它从.csv文件中获取信息,解析它,然后删除我解析的任何内容。我遇到的问题是,在它穿过.csv文件的一行之后,我得到了一个分段错误。我听说我可以使用GDB来帮助解决这个问题,但我不知道如何使用它。这是我的.c文件

void parser(int argc, char ** argv)
{
FILE * songList;
char * theString;
char * theToken;
char songs[ROOM_STRING_LENGTH];
char artist[ROOM_STRING_LENGTH];
char title[ROOM_STRING_LENGTH];
int x;
int length;
double size;
char * type;
char songType[1];
char songTypeC;
MusicRec * next;

theToken = "";


songList = fopen(argv[1], "r");

if(songList == NULL)/*returns an error if file wasnt opened*/
{
    printf("error opening file\n");
}

else
{
    while(fgets(songs, ROOM_STRING_LENGTH, songList) != NULL)/*gets one string at a time until fgets equals NULL*/
    {
        theString = malloc((sizeof(char)*(strlen(songs)+1))); /* mallocs some memory*/
        strcpy(theString, songs);
        x = 0;
        for(theToken = strtok(theString, ","); theToken; theToken = strtok(NULL, ","))
        {
            switch(x)
            {
                case 0:
                strcpy(artist, theToken);
                printf("%s\n", artist);
                break;

                case 1:
                strcpy(title, theToken);
                printf("%s\n", title);
                break;

                case 2:
                sscanf(theToken, "%d",&length); 
                printf("%d\n", length);
                break;

                case 3:
                size = atof(theToken);
                printf("%.2f\n", size);
                break;

                case 4: 
                type = malloc(sizeof(char));
                sscanf(theToken, "%s",type);
                songType[0] = *type;
                songTypeC = songType[0];
                printf("%c\n", songTypeC);
                free(type);
                break;
            }
            x++;

        }
        next = malloc(sizeof(MusicRec));
        next = createRecord(title, artist, size, length, songTypeC);
        /*print = printRecord(toPrint);*/
        destroyRecord(next);  
        /*free(print);*/
        free(next);
    }

free(theString);
free(theToken);
fclose(songList);

}
}
以下是被调用的两个函数:

char * printRecord(MusicRec * toPrint)
{
char token[ROOM_STRING_LENGTH];
char * pointer;

sprintf(token, "%s (%s):%d[%.2f]", toPrint->title, toPrint->artist, toPrint->lengthInSeconds, toPrint->sizeInKB);
pointer = malloc(sizeof(char)*strlen(token));
strcpy(pointer, token);
return(pointer);
}


void destroyRecord(MusicRec * theRecord)
{
free(theRecord->title);
free(theRecord->artist);
}

看看这段代码:

case 4: 
  type = malloc(sizeof(char));
  sscanf(theToken, "%s",type);
您正在分配一个1字节的字符串,并将任意长度的字符串读入其中。
如果输入标记大于1,则很容易出现segfault。

您可能需要读取。简而言之,使用调试信息(
-g
标记为GCC)构建程序,并使用程序启动
gdb
。在GDB
中运行程序,可能带有参数。当崩溃发生时,GDB将停止,让您使用
bt
命令检查函数调用堆栈,并使用
up
命令向上遍历调用堆栈。如果GDB没有在代码中停止,则向上移动堆栈,直到进入代码。你可以
打印变量的值。至少你应该在调试器中运行你的程序,并编辑你的问题以包括调用堆栈(崩溃时
bt
命令的输出)。顺便说一下,你必须记住,C中的字符串实际上比
strlen
报告的字符串多一个字符,终止的
'\0'
字符。您在几个地方没有注意到这一点。
type=malloc(sizeof(char));sscanf(标记为“%s”的类型):太小<代码>指针=malloc(sizeof(char)*strlen(token));strcpy(指针、令牌):太小<代码>下一步=malloc(sizeof(MusicRec));next=createRecord(标题、艺术家、大小、长度、歌曲类型C)。。。免费(下一个)
下一步
已修改。能否提供csv文件中的前2或3条记录?这将是一个很大的帮助。我将(sizeof(char))更改为(sizeof(char)*MAX_LENGTH),并且我仍然在进行seg断层