5 / 5 / 0
Регистрация: 15.09.2010
Сообщений: 25
1

Непонятка с кодировкой

05.08.2011, 00:22. Показов 5511. Ответов 14
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть следующий код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include "stdafx.h"
#include <iostream>
#include <string>
 
using std::wstring;
using std::getline;
using std::wcout;
using std::wcin;
using std::endl;
 
int _tmain(int argc, _TCHAR* argv[])
{
    setlocale( LC_ALL, "russian_Russia.1251" );
    
    wstring str;
    wcout << L"Введите строку на русском: ";
    getline(wcin, str);
    wcout << L"Результат: " << str << endl;
 
    wcout << endl;
    system("PAUSE");
    return 0;
}
Вопрос: почему вместо введенного мной, в ответ на запрос, русскоязычного текста, программа выводит какую-то абракадабру? Как это исправить?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
05.08.2011, 00:22
Ответы с готовыми решениями:

Непонятка с кодировкой!
Всем привет. Изучаю PHP совсем недавно и столкнулся с такой проблеммой. К главной странице сайта...

С кодировкой базы данных и кодировкой сайтом и кодировкой файла разобраться не могу
С кодировкой базы данных и сайтом файлом разобраться не могу. Я на своем сайте вывожу данные из...

непонятка
на парах нам учитель дает зделаную прогу как пример (скорей всего на студия-08) и в компютерном...

непонятка
не могу переключить нетбук asus pc 900чтобы телек был как монитор,есть вход vga сказали что нет...

14
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
05.08.2011, 00:37 2
Я решаю эту проблему с помощью ф-ции:

C++
1
2
3
4
5
6
7
8
9
10
11
12
string rus(std::string strIn)  //Русский язык
{
    string strOut=strIn;
    for(string::size_type i=0;i<strOut.length();++i)
    {
        if(strOut[i]>='А'&& strOut[i]<='п' )
            strOut[i]-=64;
        if(strOut[i]>='р'&& strOut[i]<='я' )
            strOut[i]-=16;
    }
    return strOut;
}
0
5 / 5 / 0
Регистрация: 15.09.2010
Сообщений: 25
05.08.2011, 00:50  [ТС] 3
Avazart
К сожалению, для wstring эта функция работает не корректно...
Для string функция тоже работает не корректно. Начинает работать только если закомментить строку setlocale( LC_ALL, "russian_Russia.1251" ), но это не есть гуд...

P.S: У меня VS2010 Pro
0
594 / 532 / 76
Регистрация: 22.03.2011
Сообщений: 1,585
05.08.2011, 03:00 4
попробуй убери нафиг
setlocale( LC_ALL, "russian_Russia.1251" );

у меня этот код отрабатывает
C++
1
2
3
    std::wstring c;
    std::getline(std::wcin,c);
    std::wcout << c;
0
Android Programmer
141 / 142 / 10
Регистрация: 08.12.2010
Сообщений: 421
05.08.2011, 03:55 5
Цитата Сообщение от Oleg_SK Посмотреть сообщение
Вопрос: почему вместо введенного мной, в ответ на запрос, русскоязычного текста, программа выводит какую-то абракадабру? Как это исправить?
Потому что строка записывается в кодировки Oem(старая досовская). А когда выводите, используется кодировка Ansi.
При работе со строками например типа char, проблема решается использование функции OemToAnsi, как её применить к wstring не знаю)
0
5 / 5 / 0
Регистрация: 15.09.2010
Сообщений: 25
05.08.2011, 06:53  [ТС] 6
OstapBender
У меня предложенный вариант тоже нормально отрабатывает, но тут затык в том, что стоит в этот код добавить вывод в консоль текста заданного в программе (например: wcout << L"Введите строку на русском: ") и работа программы сразу становится некорректной... Чтобы это исправить приходится вставлять в код строку: setlocale( LC_ALL, "russian_Russia.1251" ), но после ее вставки начинается безобразие с выводом текста полученного от getline... Хочу попробовать похимичить с командой setlocale. Подскажите, плиз, как отменить действие команды setlocale( LC_ALL, "russian_Russia.1251" ), чтобы кодировка вернулась на дефолтную?

Добавлено через 29 минут
Вроде бы разобрался! В таком виде программа работает:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include "stdafx.h"
#include <iostream>
#include <string>
#include <windows.h>
 
using std::wstring;
using std::getline;
using std::wcout;
using std::wcin;
using std::endl;
 
int _tmain(int argc, _TCHAR* argv[])
{
    wstring c;
 
        setlocale( LC_ALL, "russian_Russia.1251" );
    wcout << L"Тест_1" << endl;
 
    setlocale(LC_ALL, "russian_Russia.866");
    getline(wcin,c);
    wcout << c << endl;
 
    setlocale( LC_ALL, "russian_Russia.1251" );
    wcout << L"Тест_2" << endl;
 
    wcout << endl;
    system("PAUSE");
    return 0;
}
То есть, перед выводом в консоль заданного в программе текста нужно давать команду: setlocale( LC_ALL, "russian_Russia.1251" ), а перед вызовом getline давать команду: setlocale(LC_ALL, "russian_Russia.866")...

Добавлено через 24 минуты
Осталось еще разобраться: как перекодировать строки из 866 кодировки в 1251 или обратно для типа wstring, чтобы можно было сравнивать строки введенные через getline со строками заданными в тексте программы... Может быть кто-нибудь знает, как это можно сделать?

Добавлено через 19 минут
Кажись опять сам разобрался. Вроде бы для сравнения строк не нужно приводить их к одной кодировке, т.к. метод compare класса wstring сам прекрасно с этим справляется...
0
3507 / 2669 / 329
Регистрация: 11.03.2009
Сообщений: 6,104
05.08.2011, 07:02 7
Можно сменить кодовую страницу для консоли
SetConsoleCP и SetConsoleOutputCP.
0
5 / 5 / 0
Регистрация: 15.09.2010
Сообщений: 25
05.08.2011, 07:17  [ТС] 8
Цитата Сообщение от kazak Посмотреть сообщение
Можно сменить кодовую страницу для консоли
SetConsoleCP и SetConsoleOutputCP.
В самом начале попробовал поиграться с этими командами (заменив ими команду: setlocale( LC_ALL, "russian_Russia.1251" )), но что-то у меня ничего не вышло... После выполнения строк:
C++
1
2
 SetConsoleCP(1251);
 SetConsoleOutputCP(1251);
Мало того, что русскоязычный текст заданный в программе перестал выводиться в консоли, так еще и русские буквы убежали с привычных клавиш и разбежались по клавиатуре... Я что-то не так сделал?

З.Ы: Проблема обсуждаемая в этом топике уже решена. Спрашиваю просто из любопытства...
0
Android Programmer
141 / 142 / 10
Регистрация: 08.12.2010
Сообщений: 421
05.08.2011, 07:36 9
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <iostream>
#include <string>
 
std::string narrow(std::wstring const & wstr, std::locale const & loc, char def = '?')
{
    if (wstr.empty())
        return std::string();
 
    std::string ret;
    ret.resize(wstr.length());
 
    std::use_facet<std::ctype<wchar_t> >(loc).narrow(&wstr[0], &wstr[0] + wstr.length(), '?', &ret[0]);
 
    return ret;
}
 
std::wstring widen(std::string const & str, std::locale const & loc)
{
    if (str.empty())
        return std::wstring();
 
    std::wstring ret;
    ret.resize(str.length());
 
    std::use_facet<std::ctype<wchar_t> >(loc).widen(&str[0], &str[0] + str.length(), &ret[0]);
 
    return ret;
}
 
std::string to1251(std::string const & cp866)
{
    std::string ret;
    ret.reserve(cp866.length());
 
    for (std::size_t i = 0, e = cp866.length(); i < e; ++i)
    {
        wchar_t wide = std::use_facet<std::ctype<wchar_t> >(std::locale(".866")).widen(cp866[i]);
        ret.push_back(std::use_facet<std::ctype<wchar_t> >(std::locale(".1251")).narrow(wide, '?'));
    }
 
    return ret;
}
 
int main()
{
    setlocale(LC_ALL,"rus");
    std::cout<<"Введите строку\n";
    std::string cp866;
    std::cin>>cp866; // Кодировка в консоли — CP866
    std::string cp1251 = to1251(cp866); // Преобразуем в CP1251
    std::cout<<cp1251;
    return 0;
}
как вариант=)
1
3507 / 2669 / 329
Регистрация: 11.03.2009
Сообщений: 6,104
05.08.2011, 08:07 10
Oleg_SK, а шрифт на Lucida Console меняли?
0
5 / 5 / 0
Регистрация: 15.09.2010
Сообщений: 25
05.08.2011, 08:19  [ТС] 11
silentnuke
Спасибо. Интересный код, активно использующий средства STL. А можете показать аналогичный код, но для типа wstring, а не string? То есть, чтобы функция to1251 выглядела бы так:
std::wstring to1251(std::wstring const & cp866)

P.S: Мне было бы и самому интересно модифицировать ваш пример, но, к сожалению, пока мои знания STL близки к нулю...

Добавлено через 1 минуту
kazak
Нет, не менял... А как это можно сделать и какой шрифт стоит по дефолту?
0
3507 / 2669 / 329
Регистрация: 11.03.2009
Сообщений: 6,104
05.08.2011, 08:38 12
По дефолту стоит точечный шрифт, изменить можно клацнув правой кнопкой по заголовку консоли, и выбрав Свойства.
0
5 / 5 / 0
Регистрация: 15.09.2010
Сообщений: 25
05.08.2011, 09:08  [ТС] 13
kazak
Поменял шрифт, и это дало то, что русские буквы вернулись на положенные клавиши и русский текст введенный через getline стал выводиться в консоль корректно. Русский текст, заданный в программе, по прежнему не выводится (даже крякозябликов нет) и если попытаться его выводить программа начинает работать не корректно...
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
05.08.2011, 13:41 14
Странно у меня ф-ция вроде нормально работает, брал с рабочего проекта
0
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
07.11.2012, 11:12 15
Цитата Сообщение от OstapBender Посмотреть сообщение
std::wcout << c;
У меня этот поток чего то вообще не виден.
0
07.11.2012, 11:12
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
07.11.2012, 11:12
Помогаю со студенческими работами здесь

Непонятка
Вопрос первый: Почему у меня только первое вводимое значение помещается в таблицу, а все...

Непонятка
Доброго времени суток, вообщем сразу к делу, хочу сделать как тут http://make-up.org.ua/ с лева...

Непонятка с IE
Здравствуйте! В шапке сайта есть картинка которая имеет заданную высоту. Во всех браузерах...

Непонятка с сессией
Может кто пояснить почему так происходит? есть 2 страницы, page1.php и page2.php page1.php:...

fstream непонятка
скажите,плз,правильно ли я открываю файл с fstream, и где должен лежать сам файл? #include...

Непонятка с tiny13
Делаю маячок на tiny13 и наткнулся не непонятную вещь. Ткните носом что я делаю не так? Из...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru