簡體   English   中英

使用 sscanf 和 fgets 讀取文本

[英]Reading text with sscanf and fgets

所以我的文本文件看起來類似於這個

1. First 1.1
2. Second 2.2

本質上是一個整數,字符串,然后是一個浮點數。

理論上使用sscanf()fgets() ,我應該能夠掃描它(我必須以這種格式進行掃描)但只能得到整數有人可以幫助指出我做錯了什么嗎?

while(!feof(foo))
{
  fgets(name, sizeof(name) - 1, foo);
  sscanf(name,"%d%c%f", &intarray[i], &chararray[i], &floatarray[i]);
  i++;
}

其中intarraychararrayfloatarray是一維數組, i是初始化為 0 的int

循環結構錯誤; 您不應該像那樣使用feof()並且您必須始終檢查fgets()sscanf() 此代碼也避免了輸入數組溢出。

enum { MAX_ENTRIES = 10 };
int   i;
int   intarray[MAX_ENTRIES];
float floatarray[MAX_ENTRIES];
char  chararray[MAX_ENTRIES][50];

for (i = 0; i < MAX_ENTRIES && fgets(name, sizeof(name), foo) != 0; i++)
{
    if (sscanf(name,"%d. %49s %f", &intarray[i], chararray[i], &floatarray[i]) != 3)
        ...process format error...
}

注意主要變化:

  1. 整數后面的點必須由格式字符串掃描。
  2. chararray必須是一個二維數組才能有意義。 如果您使用%c讀取單個字符,它將在第一個數字之后包含空格,並且后續轉換規范(對於浮點值)將失敗,因為字符串名稱不是浮點值。
  3. chararray[i]是二維數組時, chararray[i]前面的& 如果您真的從示例數據中讀取一維字符數組中的單個字符,而不是整個字符串,例如“First”或“Second”,則需要它。
  4. 該測試檢查三個值是否已成功轉換。 任何較小的值都表示存在問題。 使用sscanf() ,如果字符串中沒有任何內容供第一個轉換規范處理(空字符串,所有空格),您只會返回 EOF; 如果第一個非空白是字母或標點符號而不是+-等,則返回 0 。

如果您真的想要一個字符而不是名稱,那么您必須安排讀取單詞中的額外字符,可能使用:

    if (sscanf(name,"%d %c%*s %f", &intarray[i], chararray[i], &floatarray[i]) != 3)

%c之前有一個空格,這很關鍵; 它將跳過輸入中的空格,然后%c將選擇第一個非空白字符。 %*s將讀取更多字符,跳過任何空格(不會有任何空格),然后掃描一串字符直到下一個空格。 *禁止賦值; 掃描的數據不會存儲在任何地方。

fgets()sscanf()范式的主要優點之一是,當您報告格式錯誤時,您可以向用戶報告導致問題的完整輸入行。 如果您使用原始fscanf()scanf() ,則只能報告導致問題的第一個字符,通常到行尾,然后僅當您編寫代碼來讀取該數據時。 它更加繁瑣(因此報告通常不是很小心),並且在報告試圖謹慎的極少數情況下,可用信息對用戶沒有多大幫助。

您的sscanf需要空格。

sscanf(name,"%d %s %f", &intarray[i], &chararray[i], &floatarray[i]);

如果沒有空格,則期望將所有內容混合在一起。

請注意,如果找到scanf中的單個空格,則實際上將匹配多個空格字符(例如,兩個空格或多個空格和制表符)。

字符串不會是 %s 否則它只會讀取帶有 %c 的字符,然后浮點值可能會受到影響。 嘗試“%d %s %f”

%s 無濟於事,因為它可能會讀取浮點值本身。 據我所知, %c 讀取單個字符。 然后它搜索導致問題的空間。 要掃描單詞,您可以使用循環(當然以空格結尾)。

您需要將格式字符串更改為:

"%d %s %f"

空格是因為你的輸入數據中有空格, %s是因為你想在那個時候讀取一個多字符的字符串( %c只讀取一個字符); 不過不用擔心,因為%s不會讀過一個空格。 當然,您需要確保目標緩沖區中有足夠的空間來讀取字符串。

如果您只想要第二個單詞的第一個字符,請嘗試:

"%d %c%s %f"

並添加一個額外的(虛擬)緩沖區來接收您想要丟棄的%s解析的字符串。

暫無
暫無

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

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