簡體   English   中英

使用fscanf逐行遍歷FILE

[英]Traverse FILE line by line using fscanf

好的,我有一個文本文件database.txt。

每行都是具有以下格式的用戶

"John Smith"| 4| 80.00| "123 Lollipop Lane"| "New Jersey"| "08080"  

當我嘗試執行以下操作時:

database = fopen(fileName,"r"); 
    while(fscanf(database,"%[^\n]", buffer) != EOF){ 
        printf("ATTEMPT TO: Insert user %s\n\n", buffer); 
        if (insert_Customer(clients, create_Customer(buffer)) < 0){ 
            printf("\nERROR: Failed to insert and create customer %s\n", buffer); 
        } 
        else printf("\nSUCCESS: Inserted Customer %s\n\n", buffer); 
    } 

它在第一行運行正常,將ENTIRE行發送到create_Customer(char * buffer)函數。 出於某種原因,我不明白,在第一行之后它不斷嘗試發送“John Smith”而不是繼續前進到下一行。 我相信我的格式不正確,但我無法弄清楚如何完成我想要完成的工作,逐行讀取此文件並將每行傳遞給create_Customer函數。

我認為你需要在你的模式中關閉\\n 我看到一堆滾動文本與%[^\\n]相同的第一行,但是%[^\\n]\\n我看到了預期的輸出。

但是,如果文件中的行超過緩沖區的行,則可能會遇到緩沖區空間不足的問題。 結果

測試v1:

#include <stdio.h>


int main(int argc, char * argv[])
{
    FILE * database;
    char buffer[30];

    database = fopen("test.txt", "r");

    if (NULL == database)
    {
         perror("opening database");
         return (-1);
    }

    while (EOF != fscanf(database, "%[^\n]\n", buffer))
    {
         printf("> %s\n", buffer);
    }

    fclose(database);
    return (0);
}

結果

> 12343456567856789
> zbasdflkjasdfkjklsdafjklas
> zxcvjkleryjkldhfg
> 1234567890123456789012341234
> 12345678901234567890123123asdfjklzxcv;jkl;eqwrtjklkzlcxvjkleqrt41234
*** stack smashing detected ***: ./fscanf terminated                                                                                                                   
Segmentation fault (core dumped)

測試v2:

讓我們修復代碼,這樣我們就不會超出緩沖區。 我們通過將%[^\\n]\\n更改為%30[^\\n]\\n 這告訴fscanf它只能使用最大緩沖區大小 - 30。

#include <stdio.h>


int main(int argc, char * argv[])
{
    FILE * database;
    char buffer[30];

    database = fopen("test.txt", "r");

    if (NULL == database)
    {
         perror("opening database");
         return (-1);
    }

    while (EOF != fscanf(database, "%30[^\n]\n", buffer))
    {
         printf("> %s\n", buffer);
    }

    fclose(database);
    return (0);
}

結果

它看起來像是有效的!

> 12343456567856789
> zbasdflkjasdfkjklsdafjklas
> zxcvjkleryjkldhfg
> 1234567890123456789012341234
> 12345678901234567890123123asdf
> jklzxcv;jkl;eqwrtjklkzlcxvjkle
> qrt41234

的test.txt

這就是我正在使用的測試文件。

12343456567856789
zbasdflkjasdfkjklsdafjklas
zxcvjkleryjkldhfg
1234567890123456789012341234
12345678901234567890123123asdfjklzxcv;jkl;eqwrtjklkzlcxvjkleqrt41234

你使用fscanf而不是fgets任何原因?

有一點需要注意,如果你使用fgets ,你可能想要fgets \\n字符,因為它將作為字符串的一部分包含在內。

來自cplusplus.com fgets

從流中讀取字符並將它們作為C字符串存儲到str中,直到讀取(num-1)個字符或者到達換行符或文件結尾,以先發生者為准。

例:

/* fgets example */
#include <stdio.h>

int main()
{
    FILE * database;
    int res;
    char buffer [100];

    database = fopen(fileName,"r");

    if (NULL == database) {
        perror("opening database file");
        return (-1);
    }

    /* while not end-of-file */
    while (!feof(database)) { 

        /* we expect buffer pointer back if all is well, get out if we don't get it */
        if (buffer != fgets(buffer, 100, database))
            break;

        /* strip /n */
        int len = strlen(buffer);
        if (buffer[len - 1] == '\n')
            buffer[len - 1] = 0;

        printf("ATTEMPT TO: Insert user %s\n\n", buffer); 

        if (insert_Customer(clients, create_Customer(buffer)) < 0)
            printf("\nERROR: Failed to insert and create customer %s\n", buffer); 
        else
            printf("\nSUCCESS: Inserted Customer %s\n\n", buffer);
    }

    /* a little clean-up */
    fclose(database);

    return (0);
}

問題是你的fscanf永遠不會在第一行的末尾讀取換行符。 因此,當它第二次被調用時,它將失敗(返回0,而不是EOF)並且什么都不讀,保持buffer不變。

您可以添加對fscanf("%*[\\n]");的調用fscanf("%*[\\n]"); 在while循環結束時跳過換行符(以及可能出現的任何空行)。 或者你可以只使用fgets ,這也可以更容易避免潛在的緩沖區溢出問題。

你必須使用fgets而不是fscanffscanf讀取它直到它\\ n(新行)字符,而你可以使用fgets讀取所有使用完全相同代碼的行! 希望有幫助:)

您應該在說明符“%[^ \\ n]”之后放置一個空格或使用“%[^ \\ n] \\ n”。 兩者都允許您跳過換行符。

fscanf(database, "%[\n] ", buffer);

要么

fscanf(database, "%[\n]\n", buffer);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM