2010-03-17 189 views
4

如何找出当前的C++字符集?如何查找C++中当前的字符集是什么?

在一个控制台应用程序(操作系统)我与

(int)mystring[a] 

越来越负值对于一些字符(比如äöüé),这令我感到奇怪。我期待值在127和256之间。

那么在C++中有什么像GetCharset()或SetCharset()?

+2

什么类型是mystring? – 2010-03-17 13:45:23

+0

你期望什么价值?您可以获取当前的语言环境,然后找出与该语言环境和编码对应的字形ID(松散地说)。最有可能的是,字形ID大于int可以在系统上保存的大小。此外,如果'mystring'的类型是'wstring',那么你需要考虑多字节字符编码。 – dirkgently 2010-03-17 13:48:48

+0

@Daniel Daranas mystring是一个std :: string – Stef 2010-03-17 13:49:57

回答

5

这取决于你如何看待你手头的价值。 char可以被签名(例如在Windows上),或者像在其他一些系统上一样被签名。所以,你应该做的就是打印这个值作为无符号来得到你所要求的。

C++直到现在都是字符集不可知的。特别是对于Windows控制台,您可以使用:GetConsoleOutputCP

+0

我正在回答这个问题,因为你回答了第一个问题。其余的奥秘仍然是一个谜...它不是关于有符号或无符号整数的...... – Stef 2010-03-17 21:07:54

1

请看std::numeric_limits<char>::min()max()。或者如果你不喜欢打字,或者你需要一个整数常量表达式,则可以使用CHAR_MINCHAR_MAX

如果CHAR_MAX == UCHAR_MAXCHAR_MIN == 0那么字符是无符号的(如您所期望的)。如果CHAR_MAX != UCHAR_MAXCHAR_MIN < 0它们已签名(如您所见)。

在标准3.9.1/1中,确保没有其他可能性:“...一个普通字符可以采用与有符号字符或无符号字符相同的值;哪一个是实现定义的“。

这告诉你char是签名还是未签名,这就是让你感到困惑的原因。你当然不能调用任何东西来修改它:即使编译器有改变它的方法,它也可以从程序的POV中被烧入编译器中(GCC当然可以:-fsigned-char-funsigned-char)。

处理此问题的常用方法是,如果您要投charint,首先将其投射到unsigned char。所以在你的例子中,(int)(unsigned char)mystring[a]。这确保您获得一个非负值。

它实际上并没有告诉你什么字符集你的实现用于char,但我不认为你需要知道这一点。在Microsoft编译器上,答案基本上就是常用的字符编码“ISO-8859-mutter-mutter”。这意味着具有7位ASCII值的字符由该值表示,而该范围之外的值不明确,并且将由控制台或其他收件人根据收件人的配置方式进行解释。 ISO拉丁语1除非另有说明。

正确地说,字符解释的方式是特定于语言环境的,并且语言环境可以使用一大堆东西进行修改和询问,直到C++标准的结尾,这个标准我个人从未经历过,也不能建议;-)

请注意,如果字符集的效果与控制台使用的字符集不匹配,那么您可能会遇到麻烦。但我认为这与您的问题是分开的:字符是否可以是负数与charsets无关,只是char是否被签名。

0

,该标准提供了唯一出示担保是基本字符集的成员:

2.2字符集

基本执行字符集 和基本执行wide-字符 集应包含基本源字符集的所有成员 , 加上控制字符表示 警报,退格和回车, 加空字符(分别为, 空宽字符),其 表示具有全零位。对于 每个基本执行字符集, 成员的值应为 非负数并且不同于另一个 。在源和 执行基本字符集中, 上面的每个字符的值在 以上的小数位数列表中应为 ,其值大于前一个的值 。执行字符集 和执行宽字符集 分别是基本执行 字符集和基本执行 宽字符集的超集。执行 字符集的成员的 值是 实现定义的,和任何 附加成员是区域特异性

此外,类型char应该成立:

3.9.1基本类型

将对象声明为字符(char)应足够大以存储 实现的基本 字符集的任何成员。

因此,没有保证你会得到正确的值,你提到的字符。但是,请尝试使用unsigned int来保存此值(对于所有实际用途,如果要打印它们/传递给它,使用签名类型永久保存值为char永远不会有意义)。

+0

“使用有符号类型来保存char值永远没有意义”不幸的是,所有用于处理字符的C标准库函数都是这样做的。 – 2010-03-17 14:03:47

+0

他们这样做,但你最好使用'toupper((unsigned char)c);'where int c = getchar();'等等...... – dirkgently 2010-03-17 14:13:49

+0

同意(请参阅我的回答)。你必须在某个时候引入一个无符号类型,我所讨论的是它是否应该是'unsigned int'来保存该值(完全合理的所有其他都是相等的),或者'unsigned char'作为脚本中的垫脚石通往'int'(C-library-idiom)的路。 – 2010-03-17 14:21:44

0

字符默认情况下通常是签名的。 试试这个。

cout << (unsigned char) mystring[a] << endl; 
相关问题