Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/150.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在Visual Studio 2008投掷控制台中输入俄语字母时出错_C++_Visual Studio 2008_Console - Fatal编程技术网

C++ 在Visual Studio 2008投掷控制台中输入俄语字母时出错

C++ 在Visual Studio 2008投掷控制台中输入俄语字母时出错,c++,visual-studio-2008,console,C++,Visual Studio 2008,Console,可能重复: 我正在试着用俄语字母从控制台输入符号。这是密码 #include <iostream> #include <windows.h> #include <locale.h> using namespace std; void main(){ char c; setlocale(LC_ALL,"rus"); cout << "Я хочу видеть это по-русски!" << endl;

可能重复:

我正在试着用俄语字母从控制台输入符号。这是密码

#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;
}
但我有

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

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

区域设置可能错误。试一试

setlocale(LC_ALL, ""); 
这会将区域设置设置为“默认值,即从操作系统获得的用户默认ANSI代码页”。

const int N=34;
const char DosABC[N]=“ббгжзззббзббзбзбабббб;
const char WinABC[N]=“Ўўжжжжжжжжжжгжжззжжжгг1075;
std::string ToDosStr(std::string输入)
{
std::字符串输出=”;
布尔Ok;
for(无符号i=0;i

我这样做了,而且效果很好,但是欢迎大家找到更简单的答案。我假设您使用的设置是使用cp1251(西里尔字母窗口)保存源代码,并使用cp866(西里尔字母DOS)保存控制台。(这将是俄文版Windows上的默认设置。)您遇到的问题似乎是,按您的方式设置区域设置会导致输出从cp1251转换为cp866,但不会导致输入的反向转换。因此,当您在中读取字符时,程序将获得cp866表示。输出时,此cp866表示被错误地视为cp1251表示,并转换为cp866,导致ф到Ф转换

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

  • 在回显之前,手动将输入数据从cp866转换为cp1251
  • 替换
    setlocale(LC_ALL,“rus”)
    ,它通过调用
    SetConsoleCP(1251)来改变CRT处理输出的方式;SetConsoleOutputCP(1251)
    将改为更改控制台的行为(并且更改将在控制台的生存期而不是程序的生存期内持续)
  • 用使用UTF-16的Windows API替换cin和cout的使用。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;
}
#包括
#包括
#包括
void main(){
字符c;
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
std::cout>c;

std::cout.cpp文件的编码是什么?它在“另存为”对话框下的“高级保存选项”中可见。可能需要使用宽字符和字符串,以及流对象的宽字符版本(例如
std::wcout
std::wcin
)?@Ilmo Euro encoding西里尔文(Windows)-代码页1251@JohanLundberg不,它是输出,现在是输入也许更改问题的标题不,它没有帮助。当我尝试它时,它没有正确显示第一个cout。可以工作,我不确定。@Ilmo Euro我测试了我,但它不工作:(我做了setConsoleECP(866);SetConsoleOutputCP(866);它也起了作用。但现在,当我不使用setlocale(LC_ALL,“rus”)时,它的输出不正确。我认为问题在于源代码是cp1251,而要将字符串从cp1251转换为cp866,则需要
setlocale(LC_ALL,“rus”)
,以匹配对SetConsoleOutputCP(866)的调用。
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;
} 
#include <iostream>
#include <clocale>

#include <Windows.h>

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

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