2016-04-08 23 views
2

啊,一個程序員的古老故事增量寫一些代碼,他們不希望做任何事情超過預期,但意外的代碼做的一切,並正確,太。我正在處理一些C編程實踐問題,其中一個是將stdin重定向到一個文本文件,其中有一些代碼行,然後用scanf()和printf()將其打印到控制檯。我遇到麻煩換行符打印以及(因爲scanf函數通常吃掉空格字符),並輸入了涉及多個條件語句和標誌代碼,一個混亂的爛攤子時,我決定從頭開始和結束了打字:爲什麼這個scanf()轉換實際上工作?

(其中c是一個字符緩衝區大到足以容納的文本文件的內容全部)

scanf("%[a-zA-Z -[\n]]", c); 
printf("%s", c); 

而且,瞧,這完美地工作。我想,爲什麼通過創建角色職業的變化(外括號)搞清楚,如:

[\w\W -[\n]] 
[\w\d -[\n]] 
[. -[\n]] 
[.* -[\n]] 
[^\n] 

但沒有這些工作的。他們最終都只讀了一個角色或者製造了一堆亂七八糟的隨機角色。 '[^ \ n]'不起作用,因爲文本文件包含換行符,所以它只打印出一行。

因爲我還沒有想通了,我希望有人在那裏會知道答案這兩個問題:

  • 爲什麼「[A-ZA-Z - [\ NN] ]「按預期工作?
  • 文本文件包含字母,數字和符號( ':', ' - ', '>',也許有些人);如果「A-Z」的解釋是:「從Unicode所有字符‘a’到Unicode的‘Z’」,請問「A-ZA-Z」還包括數字?
  • 看起來你可以在括號內輸入的語法看起來很像正則表達式(我從Python中很熟悉),但並不完全如此。我讀過了什麼可以想弄清楚這個問題可以使用,但我一直沒能找到任何比較,這個語法是正則表達式的任何信息。那麼,他們是如何相似和不同的?

我知道這可能不是一個很好的使用scanf,但由於它來自一個實踐問題,現實世界的約定必須暫時忽略這種用法。

謝謝!

+6

字符分類格式是*不是正則表達式。請閱讀[這個'scanf'(和家庭)參考](http://en.cppreference.com/w/c/io/fscanf)瞭解更多信息。 –

+0

你在這個格式字符串中有一個從「space」到「open bracket」的範圍。 – user2357112

+0

C沒有嵌套的字符類嗎? – velocirabbit

回答

3

您正在選取數字,因爲您的字符集中有「 - [」。這意味着從空格(32)到開括號(91)的所有字符,其中包括ASCII(48-57)中的數字。

你的其他例子也包括這個,但他們缺少「a-zA-Z」,它可以讓你拿起小寫字母(97-122)。像'\ w'這樣的序列在字符串本身中被視爲未知的轉義序列,因此\w只是成爲一個單一的w.*的字面理解。它們沒有像正則表達式那樣的特殊含義。

+0

C沒有嵌套的字符類嗎?出於某種原因,我認爲它確實如此。不過,這肯定會解釋它。 – velocirabbit

+0

我剛測試過它,'%[ - 〜\ n]'的工作原理也是如此。 – velocirabbit

0

如果在[(除開頭或結尾處)包含-,則行爲是實現定義的

這意味着您的編譯器文檔必須描述行爲,因此您應該查閱該文檔以查看定義的行爲是什麼,這可以解釋爲什麼某些代碼有效,有些則不行。

如果要編寫便攜式代碼,則不能將-用作除匹配連字符之外的其他任何內容。

相關問題