2016-02-14 54 views
-1

的test1.c:打開文件會導致不同的結果

int main(int argc, char *argv[]) 
    { 
     FILE* fp = fopen("test.txt","rw"); 
     int n,m,q; 
     scanf(" %d%d%d",&n,&m,&q); 
     struct test_t test; 
     while (fscanf(fp,"%d%s%d%d%d%d%d%d%d%*d",&test.line,test.data,&test.number[0],&test.number[1],&test.number[2],&test.number[3],&test.number[4],&test.number[5],&test.number[6])!=EOF) { 
       //do something..... 
     } 
     return 0; 
    } 

的test2.c中:

int main(int argc, char *argv[]) 
{ 
    int n,m,q; 
    scanf(" %d%d%d",&n,&m,&q); 
    struct test_t test; 
    FILE* fp = fopen("test.txt","rw"); 
    while (fscanf(fp,"%d%s%d%d%d%d%d%d%d%*d",&test.line,test.data,&test.number[0],&test.number[1],&test.number[2],&test.number[3],&test.number[4],&test.number[5],&test.number[6])!=EOF) { 
      //do something.... 
    } 
    return 0; 
} 

test_t的定義:

struct test_t { 
    int line; 
    char* data; 
    int number[7]; 
}; 

我的測試。 txt:

141 2015-12-05 19 16 35 06 34 46 09 00 
124 2015-12-08 49 25 10 09 40 48 32 00 
143 2015-12-10 09 29 24 47 32 34 42 00 

當我使用test1.c時,我得到了分段錯誤。但是當我使用test2.c時,它運行良好。只改變了FILE* fp = fopen("test.txt","rw");這一行。引起這種差別的原因是什麼。

+0

您的代碼不會編譯,因爲編譯器不知道'size_t'的大小。 –

+0

@AshishAhuja我沒有發佈'test_t'的定義,我現在會發布它 – icecity96

+0

你爲什麼不發佈它?總是發佈編譯的代碼! –

回答

2

您正在調用UB,因爲您從不爲char* data;分配內存。修正:

  1. mallocwhile循環之前足夠的內存:

    test.data = malloc(32); 
    if(!test.data) 
    { 
        fprintf(stderr, "malloc failed...Bailing out!\n"); 
        exit(-1); 
    } 
    

    而且其使用後,

    free(test.data); 
    
  2. 使用預定義的大小,而不是指向char的數組:

    char data[32]; 
    

而且,@AshishAhuja said,檢查fopen也返回值。

2

那麼,當你從不同的地方運行程序時,該文件在該位置不存在的可能性很高。因此,檢查fopen是否返回NULL。這樣做:

FILE* fp = fopen("test.txt","rw"); 
if (fp == NULL) { 
    printf ("Error, file does not exist\n"); 
    exit (1); 
} 

打開不存在是沒有問題的,因爲fopen只會返回NULL的文件。嘗試讀取或寫入它將導致分段錯誤和核心轉儲。


而且,你永遠不會爲char *data分配內存,這可能會導致問題。要正確分配和釋放,請參閱@CoolGuy's答案。

+1

更糟糕的是:'test.data'未初始化:將其作爲scanf'%s'格式的接收器傳遞,肯定會調用未定義的行爲。初始化分配內存是一種可能的解決方案。 – chqrlie

相關問題