这是对此问题的一个扩展问题:Is std::string suppose to have only Ascii characters
我想构建一个简单的控制台应用程序,它将用户的输入作为一组字符。这些字符包含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(至少)数字有顺序排序。但是,在其他编码中,我不知道他们是否有。 (我很确定它们是,但不能保证,对吧?)
答案 0 :(得分:2)
如何强制用户/操作系统输入Ascii字符串
您不能,除非您让用户指定此类ASCII输入的数值。
这完全取决于用于提供std::cin
的终端实现如何将0
之类的关键笔划转换为特定数字,以及您的工具链希望将该数字与其数字的内在翻译相匹配'0'
。
您根本不应该明确地期望ASCII值(例如使用幻数),而是char
文字来提供可移植代码。对于所有字符集,my_char - '0'
将导致实际数字值的假设为真。 C ++标准在[lex.charset] / 3中声明
基本执行字符集和基本执行宽字符集应各自包含基本源字符集的所有成员,以及表示alert,backspace和回车符的控制字符,以及空字符(分别为null宽) character),其表示具有全零位。对于每个基本执行字符集,成员的值应是非负的并且彼此不同。 在源和执行基本字符集中,上述十进制数字列表中0之后的每个字符的值应大于前一个值的值。 [...]
强调我的
答案 1 :(得分:1)
您不能事先强制甚至验证。 “邪恶的用户”总是可以将UTF-8编码的字符串隐藏到您的应用程序中,没有U + 7F以上的字符。而且这样的字符串碰巧也是Ascii编码的。
此外,无论您采取何种平台特定措施,用户都可以管道UTF-16LE编码文件。或/dev/urandom
你的错误字符串编码与输入流的一些魔术属性 - 而事实并非如此。它就像JPEG或AVI一样编码,必须以完全相同的方式处理 - 读取输入,匹配格式,报告解析失败时的错误。
对于您的情况,如果您只想接受ASCII,请逐字节读取输入流,如果您遇到的值超出ASCII域的值,则抛出/退出错误。
但是,如果以后遇到一个提供带有某些不兼容编码的数据的终端,比如UTF16LE,你别无选择,只能写一个检测(基于字节顺序标记)和转换例程。