我正在尝试用俄语字母表中的控制台输入符号。这是代码
#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'周围的堆栈已损坏。
答案 0 :(得分:2)
我假设您正在使用的设置是使用cp1251(西里尔文Windows)保存源,并使用cp866(西里尔语DOS)控制台。 (这将是俄语版Windows上的默认设置。)您遇到的问题似乎是设置区域设置会导致输出从cp1251转换为cp866,但不会导致逆转换输入。因此,当您读入一个字符时,程序将获得cp866表示。输出时,此cp866表示被错误地视为cp1251表示并转换为cp866,从而导致ф到д的转换。
我认为转换只是由基于C语言环境的CRT完成的,但我不知道如何为输入启用类似的转换。让程序运行有不同的选择。
setlocale(LC_ALL,"rus")
,它改变CRT处理输出的方式,调用SetConsoleCP(1251); SetConsoleOutputCP(1251);
,这将改变控制台的行为(并且更改将在控制台的生命周期内持续,而不是在您的生命周期内程序)。以下是第二个选项的示例:
#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;
}
我做到了,它有效,但是每个人都欢迎找到更容易的答案