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

I assume the set-up you're using is to have the source saved using cp1251 (Cyrillic Windows) and to have the console using cp866 (Cyrillic DOS). (This will be the default set up on Russian versions of Windows.) The problem you're running into seems to be that setting the locale as you do causes output to be converted from cp1251 to cp866, but does not cause the inverse conversion for input. So when you read a character in, the program gets the cp866 representation. This cp866 representation, when output, is incorrectly treated as a cp1251 representation and converted to cp866, resulting in the ф to д transformation.

I think the conversions is just done by the CRT based on the C locale, but I don't know how to enable a similar conversion for input. There are different options for getting your program to work.

  • Manually convert input data from cp866 to cp1251 before echoing it.
  • Replace setlocale(LC_ALL,"rus") which changes how the CRT deals with output with calls to SetConsoleCP(1251); SetConsoleOutputCP(1251); which will instead changes the console's behavior (and the changes will persist for the lifetime of the console rather than the lifetime of your program).
  • Replace uses of cin and cout with Windows APIs using UTF-16. Microsoft's implementation of the standard library forces the use of legacy encodings and causes all sorts of similar problems on Windows. So just avoid it altogether.

Here's an example of the second option:

#include <iostream>
#include <clocale>

#include <Windows.h>

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

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

Assuming the source is cp1251 encoded then the output will appear correctly and an input ф will not be transformed into a д.

于 2012-08-03T14:53:56.007 に答える
0

ロケールが間違っている可能性があります。試す

setlocale(LC_ALL, ""); 

これにより、ロケールが「デフォルト、つまりオペレーティングシステムから取得したユーザーデフォルトのANSIコードページ」に設定されます。

于 2012-08-03T10:51:21.687 に答える
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;
} 

I did it, and it works, but everybody welcome to find easier answer

于 2012-08-03T11:53:50.410 に答える