3

Possible Duplicate:
I can't see the russian alpabet in Visual Studio 2008

I'm trying input symbol from console in Russian alphabet. This is code

#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;
}

I entered 'ф', but it prints 'д'. I tried to use

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

But I have

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

And then I have an error Run-Time Check Failure #2 - Stack around the variable 'str' was corrupted.

4

3 回答 3

2

我假设您使用的设置是使用 cp1251 (Cyrillic Windows) 保存源代码并使用 cp866 (Cyrillic DOS) 保存控制台。(这将是俄语版本的 Windows 上的默认设置。)您遇到的问题似乎是设置区域设置会导致输出从 cp1251 转换为 cp866,但不会导致反向转换输入。所以当你读入一个字符时,程序会得到 cp866 表示。这个 cp866 表示在输出时被错误地视为 cp1251 表示并转换为 cp866,从而导致 ф 到 ä 转换。

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

  • 在回显之前手动将输入数据从 cp866 转换为 cp1251。
  • 替换setlocale(LC_ALL,"rus")which 会更改 CRT 处理输出的方式,而调用SetConsoleCP(1251); SetConsoleOutputCP(1251);which 将更改控制台的行为(并且更改将在控制台的生命周期内持续存在,而不是在程序的生命周期内持续存在)。
  • 将 cin 和 cout 的使用替换为使用 UTF-16 的 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 编码的,那么输出将正确显示,输入 ф 不会转换为 ä。

于 2012-08-03T14:53:56.007 回答
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;
} 

我做到了,它有效,但欢迎大家找到更简单的答案

于 2012-08-03T11:53:50.410 回答
0

语言环境可能是错误的。尝试

setlocale(LC_ALL, ""); 

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

于 2012-08-03T10:51:21.687 回答