2011-04-12 107 views
0

我想從文件中讀取特定行,並且可以獲取行號,但我不知道如何去做,這是迄今爲止:C - 從文件中讀取特定行

#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 

int main(int argc, char **argv) 
{ 
    FILE *file; 
    file = fopen("temp.txt","r"); 
    char tmp[256]={0x0}; 
    char *tmpline; 
    int numline = 1; 
    while(file != NULL && fgets(tmp, sizeof(tmp),file) !=NULL) 
    { 
    tmpline = strstr(tmp,"status:green"); 

    if(tmpline) { 
     printf("%d - %s", numline, tmpline); 
    } 

    numline++; 
    } 
    if (file != NULL) fclose(file); 

    return 0; 
} 

測試文件看起來像:

s1.server.com 
127.0.0.1 
status:green 

s2.server.com 
127.0.0.1 
status:red 

s3.server.com 
127.0.0.1 
status:red 

s4.server.com 
127.0.0.1 
status:green 

的輸出,我是:

3 - status:green 
15 - status:green 

但我真的想表明的是:

s1.server.com 
s4.server.com 

我希望它搜索「狀態:綠色」再回去了幾行,以顯示它屬於

+1

爲什麼要重新發明輪子?這可以通過一個awk單行程來解決 - 例如'awk tdammers 2011-04-12 14:32:03

+0

@tdammers,不完全是這樣:zoite想要在他看到時顯示一個*更早的*行「狀態:綠色」。你仍然可以通過簡單的awk調用來實現,但並不那麼容易。 – 2011-04-12 14:36:38

+1

這可能是如此,但他問如何在C. – James 2011-04-12 14:39:33

回答

1

聽起來好像你需要做兩件事情之一的服務器。

簡單選項:保留一些循環的緩衝區行。讀入第0行,第1行,第2行,...,第n-1行,第0行,第1行等。然後,當你看到你想要的文本時,查看條目(current_index - 2)mod buffer_size。 (這聽起來好像3緩衝區大小就足夠了。)

更復雜的選項:其實解析輸入,使每個塊你的工作的服務器名,IP地址和它的狀態,然後使用它顯示您需要的信息。

「更復雜的選項」將會有更多的工作,但如果輸入的語法發生變化(例如,通過可選的額外的行以及更多關於服務器的信息 - 多個IP地址或多個名稱) )。

還有一些其他的事情我可以做,我認爲更糟。 (1)在每行上調用ftell,將的結果放入循環緩衝區,然後在看到「status:green」時使用fseek。 (2)使用你現有的代碼閱讀整個文件,建立一個「好」的服務器行號列表。然後再次瀏覽文件並報告好的文件。我認爲這些都比我上面列出的方法更醜陋,效率更低。有一個可能的優點:你可以使它們適應計數在由空行分隔的「節」,而不需要正確地解析事情。這會讓你成爲我提到的「更復雜」方法的靈活性的一部分,而不需要適當的解析器。

這裏是一個混合的可能性:不要使用循環緩衝區,但是如果需要可以增加大小。每次看到空行時,從緩衝區中的第一個入口開始。如果有「長」節,讓緩衝區增長。然後,當你看到「狀態:綠色」時,在緩衝區中保存的(可能是完整的)節上進行所需的任何處理。

當然,如果您確定文件格式永遠不會改變,以上都不是必需的。

+0

我很確定這是在2點之前,現在是1。如果誰低估了這一點,那麼我會非常有興趣知道你認爲哪些是錯誤的(誤導性的,不清楚的,無聊的),以便我可以改進它,並且/或者在下一次做的更好。謝謝! – 2011-04-12 14:56:19

+0

謝謝,這應該完美。不知道爲什麼我沒有想到之前 – zoite 2011-04-12 15:03:48

0

閱讀每組中的第一行和第三行。搜索status:green,如果找到,則打印服務器名稱。

1

如果測試文件(和生產文件)是格式良好的,那麼你可以做類似下面的事情(爲簡潔起見,省略錯誤檢查!):

typedef struct _SERVERSTATUS 
{ 
    char* name; 
    char* ip; 
    char* status; 
} SERVERSTATUS; 


SERVERSTATUS ss; 

ss.name = calloc(256); 
ss.ip = calloc(256); 
ss.status = calloc(256); 

while (!feof(file)) 
{ 
    fgets(ss.name, file); 
    fgets(ss.ip, file); 
    fgets(ss.status, file); 

    if (!strcmp(ss.status, "status:green")) 
     printf("%s\n", ss.name); 
} 

free(ss.name); 
free(ss.ip); 
free(ss.status); 

編輯:您還必須處理文件條目之間的空白!那就是這個,留給練習者

+0

感謝您的代碼,我將與您和Gareths的解決方案一起工作,我應該很樂意去 – zoite 2011-04-12 15:05:02