解析文本文件时获取分段错误

时间:2011-10-31 17:36:39

标签: c linux

我正在做一些简单的逻辑来解析逗号分隔的文本文件。因为我给sz + 1,所以我在最外面的while循环中得到分段错误。但相反sz + 1我使用了sizeof(str1),然后我顺利地摆脱了它,但结果没有准确捕获。在完成总迭代后,我在最后得到分段错误核心转储错误。 请任何人帮助我...

    int main()
      {
        char *str1;
        unsigned char user_id[10]="",pwd[10]="",name[75]="",frm_dt[15]="", to_dt[15]="", ntry_dt[15]="",lim_amt[15]="",act_flag[5]="";
            char *ptr;
            char *temp;
            int i=1,t,rc=0,sz=0;
            char delims[]=",";
            char filename[100] = "/home/erpdirect/Desktop/billcollectors.txt";
            FILE *fp;
            temp = (char*)malloc(strlen(ptr)+1);
            rc=0;
            fp= fopen("/home/erpdirect/Desktop/billcollectors.txt","r");
            if (fp == NULL)
            {
                printf("No such file");
                //return 1;

            }
            fseek(fp, 0L, SEEK_END);
            sz = ftell(fp);
            fseek(fp, 0L, SEEK_SET);
            printf("Size of File : %d \n",sz);
            printf("\nLoop is in file pointer\n");
            str1 =(char*)malloc(sz*sizeof(char));
            while(fgets(str1,sz+1,fp) !=NULL)
            {

                printf("\n");

                ptr=strtok(str1,delims);
                //printf("\nPoints to >>>>>>>>>  %s",ptr);
                while(ptr != NULL)
                {
                    i=1;
                    memset(user_id,0,sizeof(user_id));
                    memset(name,0,sizeof(name));
                    memset(pwd,0,sizeof(pwd));
                    memset(frm_dt,0,sizeof(frm_dt));
                    memset(to_dt,0,sizeof(to_dt));
                    memset(lim_amt,0,sizeof(lim_amt));
                    memset(ntry_dt,0,sizeof(ntry_dt));
                    memset(act_flag,0,sizeof(act_flag));

                    while(ptr!=NULL && i<=16)
                    {
                        strcpy(temp, ptr);

                        printf("\nTemp values are : %s",temp);
                        ptr = strtok(NULL,delims);
                        //printf("\nPoints to >>>>>>>>>  %s",ptr);
                        switch(i)
                        {
                            case 1: strcpy(user_id,temp);
                                printf("\nUSER ID: %s",user_id);
                                    break;//insert into categoryId  

                            case 2: strcpy(pwd,temp);   
                                printf("\nPASSWORD: %s",pwd);   break;

                            case 3: strcpy(name,temp);
                                printf("\nName: %s",name);      break; 

                            case 4: strcpy(frm_dt,temp);    
                                printf("\nFROM DATE: %s",frm_dt);   break;

                            case 5: strcpy(to_dt,temp);     
                                printf("\nTO DATE: %s",to_dt);      break;

                            case 6: strcpy(lim_amt,temp);       
                                printf("\nLIMIT Amt: %s",lim_amt);  break;

                            case 7: strcpy(ntry_dt,temp);       
                                printf("\nEntry Date: %s",ntry_dt);     break;

                            case 8: strcpy(act_flag,temp);      
                                printf("\nActive flag: %s",act_flag);           break;

                            default:break;

                        }//switch

                        i++;    
                    }//while

                }//while

            }//while 

            free(str1);
            free(temp);  

            fclose(fp);

            return SUCCESS;
        }

2 个答案:

答案 0 :(得分:2)

使用调试器。添加一些#include后,将SUCCESS更改为EXIT_SUCCESS,以下是GDB提供的内容:

(gdb) run
Starting program: /tmp/test 

Program received signal SIGSEGV, Segmentation fault.
0x0000000000400a00 in main () at test.c:14
14                  temp = (char*)malloc(strlen(ptr)+1);

现在,您可以使用调试器来检查变量。我们来看看ptr

(gdb) p ptr
$1 = 0x0

当然,不允许在strlen上拨打NULL。当您查看实际的程序源时,您可以看到在使用它之前未能初始化ptr(在这种情况下,它恰好获得的初始值为0)。

答案 1 :(得分:1)

当您调用strlen(ptr)时,ptr指针未初始化,并且您调用未定义的行为:

/* there is random garbage in ptr, instead of a 
 * valid address to a nul-terminated string
 */
temp = (char*) malloc(strlen(ptr)+1);

另请注意,在C中不需要在赋值的右侧(或者特别是malloc的结果)中转换void void指针,这与C ++不同。