2013-11-23 68 views
1

所以我現在有問題與我的程序。我試圖讓它打開一個文件計數行倒回,然後通過文件來存儲變量。 String String String int是文件的格式,但我在計算行數後遇到了問題。我可以將數字打印到屏幕上,但在打印後立即出現分段錯誤。我不知道爲什麼文件輸入int字符串c

int countLines(FILE * fin){ 
int count=0; 
char street[100]; 
char city[100]; 
char state[3]; 
int zip; 

do{ 
    fgets(street, 100, fin); 
    fgets(city, 100, fin); 
    fgets(state, 3, fin); 
    fscanf(fin, "%d\n", &zip); 
    count++; 
}while(!feof(fin)); 

rewind(fin); 

return count; 

}

lines=countLines(fin);是我如何調用該函數。我究竟做錯了什麼?

+0

fgets讀取整行直到文件或換行符結束。你的「String String String int」值是一行一行還是一行一行? – tyilmaz

+0

這是每個條目的一行。 字符串\ n 字符串\ n 字符串\ n int \ n – kevorski

+0

對於結果代碼,不應檢查任何*這些fgets()調用,也不要檢查fscanf()是否應放在列表頂部「what-i'm-doing-wrong」,之後不久,通過在while循環中使用'feof()'作爲中斷條件,[這幾乎總是錯誤的。](http://stackoverflow.com/問題/ 5431941/while-feof-file-is-always-wrong) – WhozCraig

回答

2

不要混合fgets()fscanf()直到你非常舒適與這些功能。他們在一起打球不好。在格式\n是一種白色的空間和將匹配任何數量的連續白色空間,包括多個\n,空格,製表符,等等

// fscanf(fin, "%d\n", &zip); 

推介避免feof()並使用來自fgets()的返回值。

feof()直到嘗試讀取文件並且未能提供char纔會成爲真。這不同於「當沒有人離開時是真的」。例如:您讀取文件的最後一個charfeof()仍然是錯誤的。代碼嘗試讀取更多(並失敗)。 現在feof()是正確的。 (並保持真實)。

是否以簡單的方式計算線條並使用對稱性。進一步考慮更多錯誤檢查。將郵政編碼行讀取爲一個字符串,然後然後將其解析爲一個整數。

int countLines(FILE * fin){ 
    int count=0; 
    char street[100]; 
    char city[100]; 
    char state[100]; 
    char zips[100]; 
    unsigned zip; 

    while (fgets(street, sizeof street, fin) != NULL) { 
    count++; 
    } 
    rewind(fin); 

    if (count%4 != 0) Handle_LineCountNotMultipleof4(); 

    // You could return here, but let's read the file again and get the data. 
    // This is likely part of OP's next step. 
    for (int i=0; i<count; i += 4) { 
    if ((NULL == fgets(street, sizeof street, fin)) || 
     (NULL == fgets(city, sizeof city, fin)) || 
     (NULL == fgets(state, sizeof state, fin)) || 
     (NULL == fgets(zips, sizeof zips, fin)) || 
     (1 != sscanf(zips, "%u", &zip))) handle_error(); 
    // Remember street, city, state, still have an ending \n 
    do_something(street, city, state, zip); 
    } 
    return count; 
} 

或者,要計算行數,請使用以下內容。如果排隊很長,在閱讀中會出現奇怪的困難,所以讓我們一起檢查一下。如果你喜歡簡單的答案,拿出這個東西line length東西。您可以使用Maxline+1作爲緩衝區大小而不是固定的100.

size_t Maxline = 0; 
    size_t Curline = 0; 
    int ch; 
    while ((ch = fgetc(fin)) != EOF) { 
    Curline++; 
    if (ch == '\n') { 
     count++; 
     if (Curline > Maxline) MaxLine = Curline; 
     Curline = 0; 
    } 
    } 
    if ((Maxline + 1) > 100) TroubleAhead() ; // Trouble with future (fgets(buf, 100, fin), use bigger buffers 
    rewind(fin); 
+0

當我試圖讓存儲到變量(街道,城市,州,郵編),我得到了countLines的函數調用後分段錯誤的值。這是什麼原因?這是我將數字打印到屏幕後。是因爲後面的\ n?你如何從int刪除尾部\ n? – kevorski

+0

@kevorski爲了調試,讓'do_something()'爲'printf('s:<%s> c:<%s> S:<%s> z:<%u> \ n「,street,city,state,zip)''。仔細檢查你的和我的'zips'(一個字符數組)和'zip'(一個整數)的用法。 – chux

+0

我得到了它的工作。現在只要有其他問題現在哈哈 – kevorski

0

fgets試圖閱讀整行,而不是一個字,這似乎是你所希望的。 因此,你傳遞給它的緩衝區不夠大,他們不會得到你想要的東西,而且你每增加一行3次就會增加一次計數,而fscan通常不會讀取一行,從而使該行的剩餘部分干擾隨着你的下一次閱讀。

如果您想閱讀單詞,請使用%s試試scanf。如果你想閱讀固定數量的字符,請嘗試fread。

+0

我知道我每4行增加一次。我使用的街道城市狀態zip是一個結構。你能舉出scanf的例子嗎?現在,我只是得到了一個空白頁面,一旦我輸入文件名@RichardPlunkett – kevorski