2016-06-21 61 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应按一个终端,则没有选择,只能写一个检测(基于字节顺序标记)和一个转换例程。