[英]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++;
}
其中intarray
、 chararray
和floatarray
是一維數組, 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...
}
注意主要變化:
chararray
必須是一個二維數組才能有意義。 如果您使用%c
讀取單個字符,它將在第一個數字之后包含空格,並且后續轉換規范(對於浮點值)將失敗,因為字符串名稱不是浮點值。chararray[i]
是二維數組時, chararray[i]
前面的&
。 如果您真的從示例數據中讀取一維字符數組中的單個字符,而不是整個字符串,例如“First”或“Second”,則需要它。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.