C++西班牙语问号

C++ spanish question mark

本文关键字:西班牙语 C++      更新时间:2023-10-16

我开始在C++中开发,我正在控制台中开发一个简单的计算器,当我的程序询问用户是否要退出时,字符"?"不会出现(西班牙语中的问题在"?"answers"?"之间)

有人能帮我吗?

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

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

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

有几种方法可以处理这个问题。

根本问题不在于控制台中不存在¿,而是控制台和C++文本编辑器对该字符的含义存在分歧。除了英语所需的字符外,两者对许多字符使用了不同的字符代码。字符代码32-126(字母、数字、标点符号和括号)是普遍相同的。然而,从西班牙语的角度来看,字符代码128到255包括所有重音字符,"u with diaeresis"(例如"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 << "250Cu240l es el primer n243mero?n";  // octal

输出:

¿Cuál es el primer número?

注意我是如何对ú和á做同样的事情的。不幸的是,像这样编写字符串很快就会变得笨拙。使用宏或const char可以有所帮助,但帮助不大。

第二种选择是使用诸如CharToOemA之类的Windows函数。例如1

#include <windows.h>
...
...
char pregunta[] = "¿Cuál es el primer númeron";
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控制台的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指针,那么sizeof将无法正常工作,您必须使用strlen(source)+1。对于源,我使用了将char数组初始化为文字的自然选项,但对于目标,您不能这样做,因为这样的数组的内容是只读的。如果您使用的是新的字符数组或未初始化为文字的字符数组,则可以对源和目标使用相同的字符数组。这个例子感觉很像C

您可以使用_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了。它抛出一个断言。

检查这个答案。

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

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

您只需在cmd:中调用以下命令即可完成此操作

chcp 65001

2.确保您使用的字体包含要显示的字符

Lucidia控制台应该做到这一点,因为它支持?(以及WGL4中包含的其他角色)。

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

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

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

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