2012-06-08 58 views
0

這段代碼給出了一個即時seg錯誤,我試着把printf的全部都放了,我甚至試圖在int = 0之後打印一些東西;但不管我做了什麼,它都不會打印任何內容,而只是出現分段錯誤。該文件存在,其位置也與我執行的位置相同。 該文件包含城市名稱,每行一個名稱,沒有別的,我如何讀取它們並將它們存儲在一個數組中:/ 如果在每個城市之後有一個數字,那麼讀數仍然是相同的呢?逐行讀取,seg錯誤

NewYork 5 
LosAngeles 12 
California 7 

和代碼;

int i=0; 

    char **city_names = malloc(sizeof(char*)); 

    FILE* fp; 
    fp = fopen("abc.txt","r"); 

    while(!feof(fp)){ 

     city_names[i] = realloc(city_names[i],sizeof(char)*255); 
     fscanf(fp,"%s",city_names[i]); 
     i++; 
    } 

    fclose(fp); 
+0

您應該運行在調試你的代碼;它會告訴你哪一行導致段錯誤。 –

+0

這仍然是錯誤的。您只在頂部列表中分配了1個指針。 realloc不屬於字符串大小。這是一個功課問題嗎? –

回答

2

你只在你的malloc中分配一個char *的內存,然後在while循環中訪問它。

如果你打算做一個二維數組malloc,你需要malloc每個指針,然後malloc分配malloc到每個到最大字符串大小(呸)。

char **city_names = malloc(sizeof(char *) * kNumCities); 

for(int i = 0; i < kNumCities; i++) 
    city_names[i] = malloc(sizeof(char) * kMaxStringSize); 

或者做一些類似char city_name[3][256]的替代方法來啓動並運行它。

我還想補充一點,這種閱讀非常不安全。您正在將未知數量的字節讀入固定的緩衝區大小。如果您讀入的字符串超過255個字節,則會破壞內存。你最好使用fread()進入一個固定大小的緩衝區類型的解決方案(或ftell()然後立即文件並讀取所有內容以獲得最佳效率),然後讀取緩衝區。更不要說所有的開銷mallocrealloc(他們加起來)。

+0

因爲我不知道該文件包含多少城市,我無法指定像你說的內存。我可以使用realloc出於同樣的目的嗎? – Karavana

+0

如果可能,請掃描整個文件以獲取城市計數,然後進行分配和讀取。 x2文件讀取,但內存有效。或者分配一大塊城市 - 你知道什麼是合理的 - 然後如果需要再重新分配。請注意,如果這是內存碎片很重要的嵌入式解決方案,則realloc在內存上非常困難。 –

+0

如果可能的話,我還會將整個文件讀入內存中,並從中進行處理 - 這可以爲算法等提供最大的靈活性。 –

1

而且while(!feof(fp))邏輯也是錯誤的;對於一個空文件,它仍然會嘗試掃描一些東西並增加i

在閱讀C之前,切勿測試EOF。閱讀後測試。

的慣用代碼遍歷字符上用C標準輸入是

int c; /* NOT char. */ 

while ((c = getchar()) != EOF) { 
    /* do something with c */ 
} 

遍歷行:

char line[MAXLINE]; 
while (fgets (line, sizeof line, stdin) != NULL) { 
    /* do something with line */ 
} 
+0

這真的很有用,但要使用答案的第二部分,我需要計算行數,所以我認爲編寫此代碼的最佳和簡單的方法是首先計算行數,然後嘗試那麼,謝謝:) – Karavana

+0

不需要。只需在循環前使用'int num_lines = 0;',並在裏面使用'++ num_lines'。這給你完成後的行數。如果您需要保存它們,請使用malloc和memcpy。 – Jens

1
int i=0; 
    char **city_names = malloc(sizeof(char*)); 
    FILE* fp; 
    fp = fopen("data.txt","r"); 

    while(!feof(fp)){ 
     city_names[i] = (char*)malloc(sizeof(char)*255); 
     if(1!=fscanf(fp,"%s %*d",city_names[i]))break; 
     ++i; 
     city_names = (char**)realloc(city_names, (i+1)*sizeof(char*)); 
    } 

    fclose(fp); 
+0

if(1!= fscanf(fp,「%s%* d」,city_names [i]))break; 你能否進一步解釋這一行,即爲什麼你使用%* d,我的意思是明星的目的是什麼,我知道編譯器會在我寫%d時抱怨它。 – Karavana

+1

@ user1128905 - 你的閱讀數據格式像'NewYork 5',但你的代碼是'fscanf(fp,「%s」,city_names [i]);',這是忽略int數據。 '%* d'忽略這個位置的數字數據。 – BLUEPIXY