2015-11-04 33 views
0

我通過它傳遞了一堆目錄這樣運行了我的程序:讀取損壞的文件,分段錯誤

./myprogram * 

每個目錄是一組單獨的文件中,我分析數據,然後我創建成電子表格。每個目錄都是電子表格的不同行。我只想在電子表格中放入可靠的數據,所以如果缺少一個條目,我就把它放在外面。它似乎在大多數目錄上運行良好,但在某些目錄中,我在我的一個解析函數中遇到了分段錯誤。

我注意到導致分段錯誤的每個文件都無法用gedit打開。它給出了這個錯誤:

gedit一直未能檢測到字符編碼。 請檢查您是否嘗試打開二進制文件。 從菜單中選擇一個字符編碼,然後重試。

但是,我可以通過使用cat或tail命令來顯示文件。

導致分段錯誤的特定函數是下面的fscanf函數,我一次只用一行讀取一行。 (增加緩衝區的大小沒有幫助)

char *line = malloc(1000*sizeof(char)); 
char *garbage = malloc(1000*sizeof(char)); 
while(!feof(infile)) 
{ 
    fscanf(infile,"%[^\n]%[\n]",line,garbage); 
    //parse the line 
} 

有誰知道爲什麼該文件可能無法與gedit打開?它是否損壞?有沒有一種方法可以在我的解析函數中返回錯誤代碼而不是seg錯誤?

+0

爲什麼你的程序崩潰?什麼是失敗?你看了回溯/使用了一個調試器嗎?這看起來不像'gedit'不能像gedit'那樣打開它,但我希望你可以強制它。如果你使用'cat -A file',那麼每個其他字符看起來都像'^ @'?因爲那會使它成爲UTF-16文件。 –

+0

這是一種很奇怪的方式來檢測文件結尾。 – Matt

+2

請勿使用fscanf。 1000字節不是一個大緩衝區。如果您因爲在不包含\ n的文件上運行緩衝區而超出了緩衝區,則會崩潰。使用fread,並解析緩衝區。 – Matt

回答

1

fscanf()中有一個緩衝區溢出。這可能會導致程序寫入數組末尾,覆蓋某處的指針並崩潰。

的選項有:

讀取一行到輸入緩衝區fgets()並在必要時與sscanf()解析它,可能是你想要的東西,或者

告訴緩衝區,例如的fscanf()大小fscanf(infile, " %999[^\n]%*[\n]", line);

另外,你幾乎從不想要while (!feof(infile))。當它從結尾讀取時將停止。

那麼你真的應該將其更改爲:

static const size_t LINE_LEN = 1000; 
while (fgets(line, LINE_LEN, infile)) 
    /* Do stuff with line. */ 

或者

while (1 == fscanf(infile, " %999[^\n]%*[\n]", line)) 
    /* Do stuff with line. */