1

我开始用 C++ 开发,我正在控制台中开发一个简单的计算器,当我的程序询问用户是否要退出时,字符“¿”没有出现(西班牙语中的问题在“¿”和“? ')

有人能帮我吗?

PD:这个问题只发生在 Windows 中,而不发生在 Linux 中

编辑:这是输出代码的代码:

cout << '¿' <<"Desea salir (S/N)? " ;
4

6 回答 6

3

有几种方法可以解决这个问题。

根本问题不是¿控制台中不存在 ,而是控制台和您的 C++ 文本编辑器在该字符是什么上存在分歧。两者对许多字符使用不同的字符代码,超出了英语所需的字符代码。字符代码 32-126(字母、数字、标点和括号)普遍相同。但是,从西班牙语的角度来看,字符代码 128 到 255 包括所有重音字符,“带分音符号的 u”(例如“pingüino”)、Ñ 以及开头的 ¿ 和 ¡,取决于具体环境。

为什么在字符代码上有如此不便的分歧是一个历史偶然,它本身很有趣,但超出了这个问题的范围。为简单起见:在 Windows 操作系统中,“控制台”(通常)使用OEM 代码页 437中描述的字符列表,而像 C++ 编辑器这样的 Windows 应用程序(通常)使用Windows-1252 代码页

这个问题没有可移植(通用)的解决方案,因为不同字符集的问题是特定于平台的问题。不幸的是,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我必须警告,这个片段包含一些很容易让初学者绊倒的细微之处。您必须确保文本的来源是 char 数组;如果您使用的是 char 指针,sizeof将无法正常工作,您必须使用strlen(source)+1. 对于源,我使用了初始化为文字的 char 数组的自然选项,但您不能对目标执行此操作,因为此类数组的内容是只读的。如果您使用的是新的 char 数组或未初始化为文字的数组,则可以对源和目标使用相同的 char 数组。这个例子感觉很像 C。

于 2013-07-23T14:48:52.800 回答
2

您可以使用_setmode函数来做到这一点:

#include <iostream>
#include <string>

#if defined(WIN32) && !defined(UNIX)
# include <io.h>    // for _setmode()
# include <fcntl.h> // for _O_U16TEXT
#endif // WIN32 && !UNIX

int main()
{
#if defined(WIN32) && !defined(UNIX)
    _setmode(_fileno(stdout), _O_U16TEXT);
  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#endif // WIN32 && !UNIX

    std::wstring wstr = L"'¿' and '?'";

    std::wcout << L"WString : " << wstr << std::endl;
    system("pause");
    return 0;
}

要使用 iostream 库写入 UNICODE 字符(假设 LE 是 UTF-16 的标准 Windows 变体...),请使用 _O_U16TEXT 调用 _setmode(),然后使用 wcout。

但是你不能再使用cout了。它抛出一个断言。

检查这个答案。

于 2013-07-23T11:37:12.210 回答
1

假设您正在使用对 的简单调用std::cout,如果您将命令行设置为 Unicode 模式,您应该能够打印 Unicode 字符串:

1. 将代码页更改为 UTF-8

你可以通过简单地在你的 cmd 中调用下面的命令来做到这一点:

chcp 65001

2.确保您使用的字体具有您要显示的字符

Lucidia Console 应该可以解决问题,因为它支持 ¿ (以及WGL4中包含的其他字符)。

于 2013-07-23T11:41:46.340 回答
0

这个字符根本不包含在基本 ascii 中。尝试使用 wstring http://www.cplusplus.com/reference/string/wstring/

于 2013-07-23T11:26:19.413 回答
0

正如您在Ascii 表中看到的,符号 ¿ 的代码为 168。您可以在输出流中使用 \ddd 来打印一些特殊字符。

于 2013-07-23T11:32:56.540 回答
0

这是因为命令控制台默认不支持非 ASCII 字符(ASCII 以英文字符为主,重音字符很少)。要获得对其他字符类中字符的支持,请使用该chcp命令。请参阅此处的文档。

在您的情况下,我认为您需要chcp 850在运行程序之前在控制台中运行。

于 2013-07-23T11:38:49.163 回答