[英]using fscanf to read in items
有一個文件a.txt看起來像這樣:
1 abc
2
3 jkl
我想將此文件的每一行讀取為int
和字符串,如下所示:
fp = fopen("a.txt", "r");
while (1) {
int num;
char str[10];
int ret =fscanf(fp, "%d%s", &num, str);
if (EOF == ret)
break;
else if (2 != ret)
continue;
// do something with num and str
}
但是有一個問題,如果a.txt中的一行僅包含一個num,沒有任何字符串(就像第2行一樣),那么上面的代碼將停留在該行中。
有什么辦法跳到下一行嗎?
分兩個步驟進行:
fgets()
閱讀整行。 假設您可以對要支持的行數設置簡單的靜態限制,但是通常是這種情況。 sscanf()
檢查並分析該行。 這可以解決您遇到的問題,通常是解決此類問題的更好方法。
更新 :試圖回應您的評論。 以我的方式來看,最簡單的方法是始終讀取完整的行(如上),然后解析出您認為由其組成的兩個字段:數字和字符串。
如果使用sscanf()
進行此操作,則可以使用返回值來弄清楚它的運行方式,就像您在代碼中使用fscanf()
進行嘗試一樣:
const int num_fields = sscanf(line, "%d %s", &num, str);
if( num_fields == 1 )
; /* we got only the number */
else if( num_fields == 2 )
; /* we got both the number and the string */
else
; /* failed to get either */
不知道什么時候不需要“字符串”; 它在那兒或不在那兒。
如果字符串的第一個字符為\\r or\\n
則為空字符串。 您可以使用比較。 如果單詞中包含空格(或空行),則fscanf()不適合。在這種情況下,最好使用fgets()
如何解決“使用fscanf”:
在int
,查找空格(不保存),然后查找不是'\\n'
char
。
int num;
char str[10];
#define ScanInt "%d"
#define ScanSpacesDontSave "%*[ ]"
#define ScanUntilEOL "%9[^\n]"
int ret = fscanf(fp, ScanInt ScanSpacesDontSave ScanUntilEOL, &num, str);
if (EOF == ret) break;
else if (1 == ret) HandleNum(num);
else if (2 == ret) HandleNumStr(num, str);
else HadleMissingNum();
如果將某些內容掃描到str
, ret
將為2,否則ret
通常將為1。上面的技巧是不要在int
之后掃描'\\n'
。 因此,代碼不能使用"%s"
或" "
"%d"
之后的"%d"
,它們都占用了所有(前導)空白。 下一個 fscanf()
調用將通過"%d"
消耗'\\n'
作為前導空白消耗的一部分。
小注釋:使用fgets()
讀取行然后解析緩沖區通常是一種更好的方法,但是編碼目標可能會阻止這種情況。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.