有人可以解釋這是如何工作的?我知道它讀取一個字符串(包含空格),但我並不真正理解背後的機制。有人可以一塊一塊地向我解釋 嗎?在C中讀取字符串的詳細信息?
scanf("%[^\n]%*c",string);
有人可以解釋這是如何工作的?我知道它讀取一個字符串(包含空格),但我並不真正理解背後的機制。有人可以一塊一塊地向我解釋 嗎?在C中讀取字符串的詳細信息?
scanf("%[^\n]%*c",string);
從手冊頁:
所有轉換由%(百分號)推出字符
A轉換是我們如何匹配特定的文本字符串。例如,一個%s
匹配一個字符串,而%d
匹配一個十進制整數。所以看看你的字符串,我們有一個"%[
轉換,它根據手冊頁:
[匹配來自指定的一組接受字符的非空字符序列; ...該集合由開括號[字符和右括號]字符之間的字符定義。
因此,此轉換將定義一個字符列表,它將被匹配並讀入您的字符串。對此重要的是:
如果在開括號後的第一個字符是一個迴音^,那麼這個字符集將排除這些字符。
如果你在你的字符串看起來"%[^\n]%*c"
你有%[^\n]
這意味着你匹配任何字符,直到你打一個換行符。
接下來,你有一個%*
這個明星是一個轉換,其中忽略了之後的匹配。從手冊頁:
禁止分配。隨後的轉換照常進行,但不使用指針;轉換的結果將被丟棄。如果你看看你的最後一場比賽
所以,你已經有了一個c
,
c匹配的寬度計數字符(默認爲1)的序列;
所以%*c
意味着你要匹配1個字符,然後丟棄它(字符相匹配的是新行 - 其中%[^\n]
不服用,因爲你的一切相匹配高達新行符的),它不會存儲在您的string
變量中。
閱讀手冊頁是你的朋友。我希望這有幫助。
scanf("%[^\n]%*c",string);
這是說「閱讀一切,直到一個換行符,然後讀取一個字符」。 *
(位於%*c
)是要取消分配。這是它讀取一行並消耗換行符。
從scanf()
:
可選的 '*' 分配抑制字符:scanf()的讀取所指示的轉換規格 輸入,但是丟棄該 輸入。不需要相應的指針參數,並且此規範不包含在由scanf()返回的成功分配數 中。
但是我想,對於讀取行,使用fgets()
來代替,然後消耗尾隨的換行符。
char string[256];
if (fgets(string, sizeof string, stdin) == NULL) {
/* handle failure */
}
string[strcspn(string, "\n")] = 0; /* For removing the newline if present */
這就是less error prone和更好理解。
如果您使用的是glibc,則也可以使用getline()
。
請注意,'scanf()'格式無法讀取空行,並導致在目標數組更長的行上發生緩衝區溢出。 'fgets()'方法更可取,但是在試圖去除'\ n''之前應該測試返回值,因爲如果'fgets()'失敗並且返回'NULL',string的內容是不確定的。 – chqrlie
您是否試過閱讀手冊頁?如果你在unix系統上鍵入'man scanf'並通讀它。 – EdgeCaseBerg
特別是,最後的'%* c'指示讀取終止'newline'作爲'char'並放棄結果,以免將'newline'留在輸入緩衝區中。 –
這裏是一個正則表達式的很好的參考:http://stackoverflow.com/questions/22937618/reference-what-does-this-regex-mean –