有几种方法可以解决这个问题。
根本问题不在于控制台中不存在¿,而是控制台和您的C++ 文本编辑器在该字符是什么上存在分歧。两者对许多字符使用不同的字符代码,超出了英语所需的字符代码。字符代码 32-126(字母、数字、标点和括号)普遍相同。但是,从西班牙语的角度来看,字符代码 128 到 255 包括所有重音字符,“带分音符号的 u”(例如“pingüino”)、Ñ 以及开头的 ¿ 和 ¡,取决于具体环境。
为什么在字符代码上有如此不便的分歧是一个历史偶然,它本身很有趣,但超出了这个问题的范围。为简单起见:在 Windows 操作系统中,“控制台”(通常)使用 OEM Code Page 437 中描述的字符列表,而 C++ 编辑器等 Windows 应用程序(通常)使用 Windows-1252 Code Page。
对于这个问题没有可移植(通用)的解决方案,因为不同字符集的问题是特定于平台的问题。不幸的是,Windows 的独特之处在于编辑器和(控制台)输出使用不同的集合。
第一个也是最简单的解决方案(适用于玩具程序)是从 OEM 437 代码页中查找您想要的字符代码,然后使用它。对于¿,这是#168(十六进制的0xa8,或八进制的\250)。您可以将字符代码嵌入到字符串中,以明确您要执行的操作,其中之一是:
std::cout << ""\x0a8""Cu""\x0a0""l es el primer n""\x0a3""mero?\n"; // hex
std::cout << "\250Cu\240l es el primer n\243mero?\n"; // octal
输出:
¿Cuál es el primer número?
请注意我是如何对 ú 和 á 做同样的事情的。不幸的是,像这样编写字符串很快就会变得笨拙。使用宏或const chars 会有所帮助,但作用不大。
第二种选择是使用 Windows 函数,例如 CharToOemA。例如1:
#include <windows.h>
...
...
char pregunta[] = "¿Cuál es el primer número\n";
char *pregunta_oem = new char[sizeof(pregunta)/sizeof(char)];
CharToOemA(pregunta, pregunta_oem);
std::cout << pregunta_oem;
delete []pregunta_oem;
对于更复杂的程序,我会将该模式包装到实用函数或类中。
另一种方法是更改控制台的代码页,使其与您的 C++ 编辑器和 Windows 的其余部分一致。您可以通过 CHCP 控制台命令或通过 SetConsoleOutputCP() 函数执行此操作,但这不适用于控制台使用的默认“光栅字体”,因此您还必须更改字体。当字体设置为 Lucida Console 之类的 unicode 字体时,此方法有效:
std::cout << "¿Cuál es el primer número?\n"; // ┐Cußl es el...
UINT originalCP = GetConsoleOutputCP();
SetConsoleOutputCP(1252);
std::cout << "¿Cuál es el primer número?\n"; // ¿Cuál es el...
SetConsoleOutputCP(originalCP);
(我不知道您是否可以从程序本身更改字体;我必须查一下。从控制台执行此操作的标准方法是单击角落上的小图标,单击属性,字体选项卡,然后从列表中选择一种字体)。
1 我必须警告说,这个 sn-p 包含许多可能很容易绊倒初学者的微妙之处。您必须确保文本的来源是 char 数组;如果您使用的是字符指针,sizeof 将无法正常工作,您必须使用strlen(source)+1。对于源,我使用了初始化为文字的 char 数组的自然选项,但您不能对目标执行此操作,因为此类数组的内容是只读的。如果您使用的是新的 char 数组或未初始化为文字的数组,则可以对源和目标使用相同的 char 数组。这个例子感觉很像 C。