我的工作是從文件中讀取文本的程序,並解析文本文字和操縱它們,我就是那樣的使用的fscanf解析的話我怎麼能檢查時,我跳過線
的fscanf解析當while (fscanf (fp, " %32[^ ,.\t\n]%*c", word) == 1)
{
/*manipulate the text word by word
}
我想要寫相鄰的,我覺得字,其中線我發現她
有沒有辦法,我可以檢查,當我下移一行
使用功能的fscanf當的方法嗎?
我的工作是從文件中讀取文本的程序,並解析文本文字和操縱它們,我就是那樣的使用的fscanf解析的話我怎麼能檢查時,我跳過線
的fscanf解析當while (fscanf (fp, " %32[^ ,.\t\n]%*c", word) == 1)
{
/*manipulate the text word by word
}
我想要寫相鄰的,我覺得字,其中線我發現她
有沒有辦法,我可以檢查,當我下移一行
使用功能的fscanf當的方法嗎?
最穩健的建議是使用fgets()
或許POSIX getline()
讀線,然後考慮使用 sscanf()
解析每一行。您可能需要考慮how to use sscanf()
in a loop。還有許多其他選項可用於解析該行而不是sscanf()
,例如strtok_r()
或較不理想的strtok()
- 或者在Windows上,strtok_s()
; strspn()
, strcspn()
, strpbrk()
;和其他不規範的功能。
如果您認爲必須使用fscanf()
,那麼您可能需要捕獲尾隨上下文。這方面的一個簡單的版本是:
char c;
while (fscanf(fp, " %32[^ ,.\t\n]%c", word, &c) == 2)
…
這抓住了單詞後,假設有一個。如果您的文件沒有以換行符結尾,則可能會丟失一個單詞。錯過換行也很容易。例如,如果行在換行符之前以句號結束(句號),則c
將保存.
,換行符將在下一次迭代循環中跳過。你可以克服用:
char s[33];
while (fscanf(fp, " %32[^ ,.\t\n]%32[ ,.\t\n]", word, s) == 2)
…
注意格式字符串的長度必須大於變量聲明的長度少一個!
成功調用fscanf()
後,字符串s
可能包含多個換行符和空格等。 fscanf()
函數大多不關心換行符,並且如果s
的掃描集是數據文件中的內容,它將在一行中讀取多個換行符。
如果你明確地從fscanf()
捕捉狀態,可以是,沒有一個換行符(或者一個標點符號)結尾的文件,或引起其他問題更加敏感:
char s[33];
int rc;
while ((rc = fscanf(fp, " %32[^ ,.\t\n]%32[ ,.\t\n]", word, s)) != EOF)
{
switch (rc)
{
case 2:
…proceed as normal, checking s for newlines.
break;
case 1:
…probably an overlong word or EOF without a newline.
break;
case 0:
…probably means the next character is one of comma or dot.
…spaces, tabs, newlines will be skipped without detection
…by the leading space in the format string.
break;
default:
assert(0);
break;
}
}
如果你開始關心約!
,?
,;
,:
,'
或"
字符 - 更不用說(
和)
- 生活變得更加複雜依然。事實上,在這一點上,sscanf()
的替代品開始看起來好多了。
這是很難正確地使用scanf()
家庭的功能。他們只是新手的工具,至少一旦你開始需要做任何複雜的事情。你可以看看A beginner's guide to not using scanf()
,其中包含很多有價值的信息。我不完全相信最後幾個應該是防彈用途scanf()
的例子。 (正確使用sscanf()
會稍微簡單一些,但是您仍然需要了解詳細信息。)
與fgets()
然後讀線使用sscanf
解析它們:
char buff[1024];
int lineno = 0;
int offset = 0;
while (fgets(buff, 1024, fp)) {
lineno++;
offset = 0;
while (sscanf(buff + offset, " %32[^ ,.\t\n]%*c", word) == 1)
{
/* manipulate the text word by word */
}
}
在第二環路必須增加緩衝器,以便正確地解析線適當偏移。爲此,例如,您可以使用%n
來獲取讀取字節。
但請注意[在循環中使用'sscanf()'](http://stackoverflow.com/questions/3975236/how-to-use-sscanf-in-loops)。 –
謝謝,我補充說。 @JonathanLeffler –
'fscanf'不區分行,實際上大多數格式說明符都忽略所有空格。嘗試使用'fgets'來讀取每行,然後使用字符串分割函數。 –
...例如'strsep'或'strtok'及其派生詞,如果你想分析單詞。 –
'fscanf(fp,「%32 [^,。\ t \ n]%* c」,單詞)'在不同的地方跳過''\ n'':領先''''也許''* c「' 。使用'fgets()'來讀取_line_。 – chux