如何找出当前的C++字符集?如何查找C++中当前的字符集是什么?
在一个控制台应用程序(操作系统)我与
(int)mystring[a]
越来越负值对于一些字符(比如äöüé),这令我感到奇怪。我期待值在127和256之间。
那么在C++中有什么像GetCharset()或SetCharset()?
如何找出当前的C++字符集?如何查找C++中当前的字符集是什么?
在一个控制台应用程序(操作系统)我与
(int)mystring[a]
越来越负值对于一些字符(比如äöüé),这令我感到奇怪。我期待值在127和256之间。
那么在C++中有什么像GetCharset()或SetCharset()?
这取决于你如何看待你手头的价值。 char
可以被签名(例如在Windows上),或者像在其他一些系统上一样被签名。所以,你应该做的就是打印这个值作为无符号来得到你所要求的。
C++直到现在都是字符集不可知的。特别是对于Windows控制台,您可以使用:GetConsoleOutputCP
。
我正在回答这个问题,因为你回答了第一个问题。其余的奥秘仍然是一个谜...它不是关于有符号或无符号整数的...... – Stef 2010-03-17 21:07:54
请看std::numeric_limits<char>::min()
和max()
。或者如果你不喜欢打字,或者你需要一个整数常量表达式,则可以使用CHAR_MIN
和CHAR_MAX
。
如果CHAR_MAX == UCHAR_MAX
和CHAR_MIN == 0
那么字符是无符号的(如您所期望的)。如果CHAR_MAX != UCHAR_MAX
和CHAR_MIN < 0
它们已签名(如您所见)。
在标准3.9.1/1中,确保没有其他可能性:“...一个普通字符可以采用与有符号字符或无符号字符相同的值;哪一个是实现定义的“。
这告诉你char
是签名还是未签名,这就是让你感到困惑的原因。你当然不能调用任何东西来修改它:即使编译器有改变它的方法,它也可以从程序的POV中被烧入编译器中(GCC当然可以:-fsigned-char
和-funsigned-char
)。
处理此问题的常用方法是,如果您要投char
至int
,首先将其投射到unsigned char
。所以在你的例子中,(int)(unsigned char)mystring[a]
。这确保您获得一个非负值。
它实际上并没有告诉你什么字符集你的实现用于char
,但我不认为你需要知道这一点。在Microsoft编译器上,答案基本上就是常用的字符编码“ISO-8859-mutter-mutter”。这意味着具有7位ASCII值的字符由该值表示,而该范围之外的值不明确,并且将由控制台或其他收件人根据收件人的配置方式进行解释。 ISO拉丁语1除非另有说明。
正确地说,字符解释的方式是特定于语言环境的,并且语言环境可以使用一大堆东西进行修改和询问,直到C++标准的结尾,这个标准我个人从未经历过,也不能建议;-)
请注意,如果字符集的效果与控制台使用的字符集不匹配,那么您可能会遇到麻烦。但我认为这与您的问题是分开的:字符是否可以是负数与charsets无关,只是char是否被签名。
,该标准提供了唯一出示担保是基本字符集的成员:
2.2字符集
基本执行字符集 和基本执行wide-字符 集应包含基本源字符集的所有成员 , 加上控制字符表示 警报,退格和回车, 加空字符(分别为, 空宽字符),其 表示具有全零位。对于 每个基本执行字符集, 成员的值应为 非负数并且不同于另一个 。在源和 执行基本字符集中, 上面的每个字符的值在 以上的小数位数列表中应为 ,其值大于前一个的值 。执行字符集 和执行宽字符集 分别是基本执行 字符集和基本执行 宽字符集的超集。执行 字符集的成员的 值是 实现定义的,和任何 附加成员是区域特异性
此外,类型char
应该成立:
3.9.1基本类型
将对象声明为字符(char)应足够大以存储 实现的基本 字符集的任何成员。
因此,没有保证你会得到正确的值,你提到的字符。但是,请尝试使用unsigned int
来保存此值(对于所有实际用途,如果要打印它们/传递给它,使用签名类型永久保存值为char
永远不会有意义)。
“使用有符号类型来保存char值永远没有意义”不幸的是,所有用于处理字符的C标准库函数都是这样做的。 – 2010-03-17 14:03:47
他们这样做,但你最好使用'toupper((unsigned char)c);'where int c = getchar();'等等...... – dirkgently 2010-03-17 14:13:49
同意(请参阅我的回答)。你必须在某个时候引入一个无符号类型,我所讨论的是它是否应该是'unsigned int'来保存该值(完全合理的所有其他都是相等的),或者'unsigned char'作为脚本中的垫脚石通往'int'(C-library-idiom)的路。 – 2010-03-17 14:21:44
字符默认情况下通常是签名的。 试试这个。
cout << (unsigned char) mystring[a] << endl;
什么类型是mystring? – 2010-03-17 13:45:23
你期望什么价值?您可以获取当前的语言环境,然后找出与该语言环境和编码对应的字形ID(松散地说)。最有可能的是,字形ID大于int可以在系统上保存的大小。此外,如果'mystring'的类型是'wstring',那么你需要考虑多字节字符编码。 – dirkgently 2010-03-17 13:48:48
@Daniel Daranas mystring是一个std :: string – Stef 2010-03-17 13:49:57