在Visual Studio 2008中输入俄语字母的错误抛出控制台

时间:2012-08-03 10:08:41

标签: c++ visual-studio-2008 console

  

可能重复:
  I can't see the russian alpabet in Visual Studio 2008

我正在尝试用俄语字母表中的控制台输入符号。这是代码

#include <iostream>
#include <windows.h>
#include <locale.h>
using namespace std;

void main(){
    char c;
    setlocale(LC_ALL,"rus");
    cout << "Я хочу видеть это по-русски!" << endl;
    cin >> c;
    cout << c;
}

我输入'ф',但它打印'д'。我试着用

char buf[2];
char str[2];
str[0] = c;
str[1] = '\0';
OemToAnsi(buf, str);

但我有

+       str 0x0015fef4 "¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ф¦¦¦¦d §"    char [2]
+       buf 0x0015ff00 "¦¦¦ф¦¦¦¦d §"    char [2]

然后我遇到错误运行时检查失败#2 - 变量'str'周围的堆栈已损坏。

3 个答案:

答案 0 :(得分:2)

我假设您正在使用的设置是使用cp1251(西里尔文Windows)保存源,并使用cp866(西里尔语DOS)控制台。 (这将是俄语版Windows上的默认设置。)您遇到的问题似乎是设置区域设置会导致输出从cp1251转换为cp866,但不会导致逆转换输入。因此,当您读入一个字符时,程序将获得cp866表示。输出时,此cp866表示被错误地视为cp1251表示并转换为cp866,从而导致ф到д的转换。

我认为转换只是由基于C语言环境的CRT完成的,但我不知道如何为输入启用类似的转换。让程序运行有不同的选择。

  • 在回显之前,手动将输入数据从cp866转换为cp1251。
  • 替换setlocale(LC_ALL,"rus"),它改变CRT处理输出的方式,调用SetConsoleCP(1251); SetConsoleOutputCP(1251);,这将改变控制台的行为(并且更改将在控制台的生命周期内持续,而不是在您的生命周期内程序)。
  • 使用UTF-16替换cins和cout与Windows API的使用。 Microsoft对标准库的实现强制使用旧版编码,并在Windows上导致各种类似的问题。所以完全避免它。

以下是第二个选项的示例:

#include <iostream>
#include <clocale>

#include <Windows.h>

void main(){
    char c;
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);

    std::cout << "Я хочу видеть это по-русски!\n";
    std::cin >> c;
    std::cout << c;
}

假设源是cp1251编码,那么输出将正确显示,输入ф不会转换为д。

答案 1 :(得分:0)

语言环境可能有误。试试

setlocale(LC_ALL, ""); 

这将语言环境设置为“默认值,即从操作系统获取的用户默认ANSI代码页”。

答案 2 :(得分:0)

const int N = 34;
const char DosABC[N] = "абвгдеёжзийклмнопрстуфхцчшщъыьэюя";
const char WinABC[N] = " ЎўЈ¤Ґс¦§Ё©Є«¬­®Їабвгдежзийклмноп";

std::string ToDosStr(std::string input)
{
    std::string output = "";
    bool Ok;
    for (unsigned i = 0; i < input.length(); i++)
    {
        Ok = false;
        for (int j = 0; j < N; j++)
            if (input[i] == WinABC[j])
            {
                output += DosABC[j];
                Ok = true;
            }
            if (!Ok)
                output += input[i];
    }
    return output;
} 

我做到了,它有效,但是每个人都欢迎找到更容易的答案