簡體   English   中英

在fscanf()中使用[]

[英]Use of [] in fscanf()

我有一個包含以下內容的文本文件:

"abc","def","ghi"

以下工作正常讀取文件內容:

int main()
{
    char name[1024] = {0};
    FILE *file = fopen("file.txt", "r");

    while(1)
    {
        if (fscanf(file, " %[\",]s ", name) == EOF)
            break;
        if (fscanf(file, " %[a-zA-Z]s ", name) == EOF)
            break;

        printf("%s\n", name);
    }

    return 0;
}

但是,以下失敗:

int main()
{
    char name[1024] = {0}, garbage[5];
    FILE *file = fopen("file.txt", "r");

    while(1)
    {
        if (fscanf(file, " %[\",]s%[a-zA-Z]s ", garbage, name) == EOF)
            break;

        printf("%s\n", name);
    }

    return 0;
}

我正在使用MSVC ++ 08.我錯過了什么? 我正在尋找一個在while循環中使用單個fscanf()的解決方案。

有用??? 純粹運氣不好:-)

您的轉換規格意味着

" %[\",]s "
         ^= optionally skip whitespace
        ^== read a literal 's'
  ^^^^^^=== read an unlimited string of quotes and commas
 ^========= optionally skip whitespace

" %[a-zA-Z]s "
            ^= optionally skip whitespace
           ^== read a literal 's'
  ^^^^^^^^^=== read an unlimited string of letters
 ^============ optionally skip whitespace

" %[\",]s%[a-zA-Z]s "
                   ^= optionally skip whitespace
                  ^== read a literal 's'
         ^^^^^^^^^=== read an unlimited string of letters
        ^============ read a literal 's'
  ^^^^^^============= read an unlimited string of quotes and commas
 ^=================== optionally skip whitespace

我想你想要的

" %4[\",]%1023[a-zA-Z] "
                      ^= optionally skip whitespace
         ^^^^^^^^^^^^^== read a string of at most 1023 letters
  ^^^^^^^=============== read a string of at most 4 quotes and commas
 ^====================== optionally skip whitespace

除此之外, scanf返回錯誤的成功轉換次數或EOF。 當您應該與1(或2或其他)進行比較時,您將結果值與EOF進行比較:與您期望的轉化次數進行比較。

if (scanf() == 3) /* expected 3 conversions */
{ /* ok */ }
else { /* oops, something went wrong */ }
  1. 括號是他們自己的轉換說明符,而不是修飾符。 %[a-zA-Z]s表示“匹配任意數量的字母字符並分配給name ,然后匹配文字s 。刪除s字符。
  2. 如果你想匹配一些但丟棄它,使用星號而不是垃圾緩沖區: %*[\\",]
  3. 如果在文件結束之前至少有一個匹配器匹配,則scanf不會返回EOF 這意味着當文件指針位於i之后時,您將獲得錯誤的循環。 考慮測試分配的指定符的數量,或者在末尾測試另一個"%*[\\"]"以覆蓋尾隨的引號。

這也是第一個版本有效的原因。 文字s無法匹配,但第一次轉換成功,所以你得到了name而不是EOF


if (fscanf(file, " %*[\",]%[a-zA-Z] ", name) < 1)
    break;

要么

fscanf(file, " %*[\",]%[a-zA-Z]%*[\"] ", name)

刪除“s”轉換標志,如下所示:

if (fscanf(file, " %[\",]%[a-zA-Z] ", garbage, name) < 2)

請注意,我必須比較2而不是EOF,因為最后一個引號將在下一次迭代時被讀入。

編輯 :我很驚訝您的第一個代碼示例也有效,但它在Mac OS X上使用gcc運行得很好,因此這不是Microsoft特定的問題。

以下應該有效:

      if (fscanf(file, " %[\",]%[a-zA-Z] ", garbage, name) == EOF) 
        break; 

暫無
暫無

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

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