2016-06-21 41 views
2

這是這個的擴展問題:Is std::string suppose to have only Ascii characters如何強制用戶/ OS輸入ASCII字符串

我想建立一個採取從用戶的字符集輸入一個簡單的控制檯應用程序。這些字符包括0->9數字和a->z字母。

我正在處理輸入,假設它是一個Ascii。例如,我正在使用類似於:static_cast<unsigned int>(my_char - '0')的編號爲unsigned int

如何讓這個代碼跨平臺?我怎麼能說我希望輸入始終是Ascii?或者我錯過了很多概念,static_cast<unsigned int>(my_char - '0')只是一個壞的方法?

P.S.在Ascii(至少)數字已排序。但是,在其他編碼中,我不知道他們有沒有。 (我敢肯定,他們卻沒有保證,對吧?)

+3

[FYI]'的static_cast <無符號整數>(my_char - '0')'是保證在所有字符工作集C++用途。 – NathanOliver

+0

@NathanOliver嗯我懷疑..但是,這只是一個例子..我會再添加一個。謝謝 –

+1

@NathanOliver:但不是用戶可以輸入的所有字符集。在MOST字符集中,字符的ASCII範圍是相同的。但是在所有的字符集中都不是這樣。例如,EBCDIC不對ASCII碼使用相同的「char」值(''0'爲ASCII碼爲0x30,但EBCDIC爲0xF0),EBCDIC不對所有ASCII字符使用連續範圍。所以,處理它時必須考慮輸入字符集。 'std :: string'只知道'char'值,但不知道它們代表什麼。 –

回答

2

如何強制用戶/ OS輸入ASCII字符串

你不能,除非你讓用戶指定這種ASCII輸入的數字值。

這一切都取決於用來服務std::cin終端執行如何轉換像0擊鍵到一個特定號碼,你的工具鏈期望相符的編號與它的內在翻譯'0'什麼。

您不應該明確地指望ASCII值(例如使用幻數),而應該使用文字來提供便攜式代碼。 my_char - '0'將導致實際數字值的假設對於所有字符集均爲真。在C++中的標準狀態[lex.charset]/3

基本執行字符集和基本執行寬字符集應各自包含的基本來源字符集表示警報的所有成員,再加上控制字符,退格和回車符,再加上一個空字符(分別爲空寬字符),其表示全部爲零。對於每個基本執行字符集,成員的值應該是非負的並且彼此不同。 在源和執行基本字符集中,上述十進制數字列表中的0之後的每個字符的值應該大於前一個的值。 [...]

重點煤礦

+0

'如何強制用戶/操作系統輸入Ascii字符串' - 您可以 - 購買突擊步槍並站在它們後面。然後他們傾向於輸入你要求他們做的事情。 –

+0

@EdHeal我不是_columbine大屠殺風格的粉絲,強迫用戶。 :-P ...雖然用戶在這種情況下是完全無辜的,但他們可以輸入他們想要的任何東西,它是負責正確解釋這些輸入的代碼。 –

+0

編輯添加來自標準 – NathanOliver

1

你不能強迫,甚至驗證事前。 「邪惡的用戶」總是可以將UTF-8編碼的字符串隱藏到您的應用程序中,並且不會出現超過U + 7F的字符。而這樣的字符串恰好也是Ascii編碼的。

此外,無論您採取哪種平臺特定的度量方式,用戶都可以管道一個UTF-16LE編碼文件。或/dev/urandom

您的錯誤字符串編碼與輸入流的一些魔術屬性 - 而事實並非如此。編碼就像JPEG或AVI一樣,並且必須以完全相同的方式處理 - 讀取輸入,匹配格式,報告解析失敗時的錯誤。

對於你的情況,如果你想只接受ASCII,由字節讀取輸入流字節和錯誤拋出/退出,如果你曾經遇到以ASCII外域值的字節。

然而,如果以後遇到提供數據與一些不兼容編碼,像utf16le應按一個終端,則沒有選擇,只能寫一個檢測(基於字節順序標記)和一個轉換例程。