Форум программистов, компьютерный форум CyberForum.ru

Кодировки, вывод/ввод на консоль и в файл - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 17, средняя оценка - 4.94
DiffEreD
 Аватар для DiffEreD
1420 / 757 / 95
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
10.05.2013, 21:23     Кодировки, вывод/ввод на консоль и в файл #1
Помогите разобраться с кодировками, а то я в этом вопросе не очень разбираюсь. Не получается одновременно сделать правильный ввод и вывод в одной программе, все известные мне методы я уже перепробовал. Вот код:
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#include <iostream>
#include <string>
#include <fstream>
#include <windows.h>
 
int main ()
{
    //SetConsoleCP (1251); SetConsoleOutputCP (1251); //строки wstring вообще не выводит
    setlocale (0, "Russian");
    //std::locale::global(std::locale(""));
    
    //std::locale cp1251_locale("ru_RU.CP1251"); //выбрасывает исключения
    //std::locale::global(cp1251_locale);
    
    std::ifstream ifs_UTF8_BOM("D:/file_UTF8_BOM.txt");
    std::ifstream ifs_UTF8("D:/file_UTF8.txt");
    std::ifstream ifs_ANSI("D:/file_ANSI.txt");
    
    std::wifstream wifs_UTF8_BOM("D:/file_UTF8_BOM.txt");
    std::wifstream wifs_UTF8("D:/file_UTF8.txt");
    std::wifstream wifs_ANSI("D:/file_ANSI.txt");
    
    std::string str_UTF8_BOM;
    std::string str_UTF8;
    std::string str_ANSI;
    
    std::wstring wstr_UTF8_BOM;
    std::wstring wstr_UTF8;
    std::wstring wstr_ANSI;
    
    //###################################################
    
    std::getline(ifs_UTF8_BOM, str_UTF8_BOM);
    std::getline(ifs_UTF8, str_UTF8);
    std::getline(ifs_ANSI, str_ANSI);
    
    std::getline(wifs_UTF8_BOM, wstr_UTF8_BOM);
    std::getline(wifs_UTF8, wstr_UTF8);
    std::getline(wifs_ANSI, wstr_ANSI);
    
    std::cout<<"Вывод str_UTF8_BOM:\t"<<str_UTF8_BOM<<std::endl;
    std::cout<<"Вывод str_UTF8:\t\t"<<str_UTF8<<std::endl;
    std::cout<<"Вывод str_ANSI:\t\t"<<str_ANSI<<std::endl;
    
    std::cout<<std::endl;
    
    std::wcout<<"Вывод wstr_UTF8_BOM:\t"<<wstr_UTF8_BOM<<std::endl;
    std::wcout<<"Вывод wstr_UTF8:\t"<<wstr_UTF8<<std::endl;
    std::wcout<<"Вывод wstr_ANSI:\t"<<wstr_ANSI<<std::endl;
    
    //###################################################
    
    std::string str;
    std::wstring wstr;
    std::cout<<"\n\nРучной ввод:\n";
    std::cout<<"string:-> "; std::getline(std::cin, str);
    std::cout<<"wstring:-> "; std::getline(std::wcin, wstr);
    std::cout<<"string: "<<str<<std::endl;
    std::wcout<<"wstring: "<<wstr<<std::endl;
    
    //###################################################
    
    std::ofstream ofs("D:/results.txt", std::ios::app);
    ofs<<"\n#######################################################\n\n";
    
    ofs<<"Вывод str_UTF8_BOM:\t"<<str_UTF8_BOM<<std::endl;
    ofs<<"Вывод str_UTF8:\t\t"<<str_UTF8<<std::endl;
    ofs<<"Вывод str_ANSI:\t\t"<<str_ANSI<<std::endl;
    
    ofs<<std::endl;
    
    ofs.close();
    std::wofstream wofs("D:/results.txt", std::ios::app);
    
    wofs<<"Вывод wstr_UTF8_BOM:\t"<<wstr_UTF8_BOM<<std::endl;
    wofs<<"Вывод wstr_UTF8:\t"<<wstr_UTF8<<std::endl;
    wofs<<"Вывод wstr_ANSI:\t"<<wstr_ANSI<<std::endl;
    
    std::cout<<std::endl;
    return 0;
}
Результат вывода в файл и на консоль (файл получается в кодировке ANSI):
Код
ВЫВОД В ФАЙЛ
Вывод str_UTF8_BOM:	п»їР*СѓСЃСЃРєРё English Українська
Вывод str_UTF8:		Р*СѓСЃСЃРєРё English Українська
Вывод str_ANSI:		Русский English Українська

Вывод wstr_UTF8_BOM:	п»їР*СѓСЃСЃРєРё English Українська
Вывод wstr_UTF8:	Р*СѓСЃСЃРєРё English Українська
Вывод wstr_ANSI:	Русский English Українська
Знаю, что в С++11 появилась такая штука как codecvt, но как ею пользоваться пока не понял. Буду рад за любые примеры и ссылки.
P.S. OS: Windows 7, компилятор: MinGW 4.7.3 от nixman, IDE: NetBeans IDE 7.3, кодировка в проекте windows-1251, шрифт в консоли Lucida Console
Миниатюры
Кодировки, вывод/ввод на консоль и в файл  
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
10.05.2013, 21:23     Кодировки, вывод/ввод на консоль и в файл
Посмотрите здесь:

C++ Вывод в консоль\файл
C++ Ввод/вывод в файл
Ввод-вывод в файл на C++ C++
C++ ввод и вывод в файл
Ввод и вывод в файл C++
Ввод\вывод в файл C++
Ввод-вывод в файл C++
C++ Ввод/вывод кириллицы через консоль

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

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
DiffEreD
 Аватар для DiffEreD
1420 / 757 / 95
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
28.05.2013, 22:12  [ТС]     Кодировки, вывод/ввод на консоль и в файл #2
Возвращаясь к старом. Поискал немного инфы в интернете и здесь на форуме и вот, поправил свой код. Нашел полезные функции по перекодировке символов. Теперь все вводы и выводы получились. Если что не так, поправьте. Вообщем, вот код, может кому надо будет:
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include <iostream>
#include <string>
#include <fstream>
#include <windows.h>
 
// Convert a wide Unicode string to an UTF8 string
std::string utf8_encode(const std::wstring &wstr)
{
    int size_needed = WideCharToMultiByte(CP_ACP, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL);
    std::string strTo(size_needed, 0);
    WideCharToMultiByte                  (CP_ACP, 0, &wstr[0], (int)wstr.size(), &strTo[0], size_needed, NULL, NULL);
    return strTo;
}
 
// Convert an UTF8 string to a wide Unicode String
std::wstring utf8_decode(const std::string &str)
{
    int size_needed;
    if ((unsigned char)str[0] == 0xEF && (unsigned char)str[1] == 0xBB && (unsigned char)str[2] == 0xBF) //detect BOM
    {
        size_needed = MultiByteToWideChar(CP_UTF8, 0, &str[3], (int)str.size()-3, NULL, 0);
        std::wstring wstrTo(size_needed, 0);
        MultiByteToWideChar              (CP_UTF8, 0, &str[3], (int)str.size()-3, &wstrTo[0], size_needed);
        return wstrTo;
    }
    else
    {
        size_needed = MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0);
        std::wstring wstrTo(size_needed, 0);
        MultiByteToWideChar              (CP_UTF8, 0, &str[0], (int)str.size(), &wstrTo[0], size_needed);
        return wstrTo;
    }
}
 
int main ()
{
    setlocale(0, ".1251");
    
    std::ifstream ifs_UTF8_BOM("D:/UTF8_BOM.txt");
    std::ifstream ifs_UTF8("D:/UTF8.txt");
    std::ifstream ifs_ANSI("D:/ANSI.txt");
    
    std::string str_UTF8_BOM;
    std::string str_UTF8;
    std::string str_ANSI;
    
    std::getline(ifs_UTF8_BOM, str_UTF8_BOM);
    std::getline(ifs_UTF8, str_UTF8);
    std::getline(ifs_ANSI, str_ANSI);
    
    std::wstring wstr_UTF8_BOM(utf8_decode(str_UTF8_BOM));
    std::wstring wstr_UTF8(utf8_decode(str_UTF8));
 
    std::cout<<"Вывод str_ANSI:\t\t"<<str_ANSI<<std::endl;
    
    setlocale(0, "rus_rus.866");
    std::wcout<<"Вывод wstr_UTF8_BOM:\t"<<wstr_UTF8_BOM<<std::endl;
    std::wcout<<"Вывод wstr_UTF8:\t"<<wstr_UTF8<<std::endl;
   
    //############################################################
    
    setlocale(0, ".1251");
    SetConsoleCP (1251); SetConsoleOutputCP (1251); //иначе ввод русских символов в string будет не коректен
    
    std::string str;
    std::cout<<"\nВвод в консоле:\n";
    std::cout<<"string:-> "; std::getline(std::cin, str);
    std::cout<<"Вывод string: "<<str<<std::endl;
    
    //############################################################
    
    setlocale(0, ".1251");
    
    //выводим все в файл
    std::ofstream ofs("D:/results.txt", std::ios::ate); //файл будет в кодировке ANSI
    
    ofs<<"Вывод str_ANSI:\t\t\t\t\t\t\t"<<str_ANSI<<std::endl;
    ofs<<"Вывод wstr_UTF8_BOM(с перекодировкой):\t"<<utf8_encode(wstr_UTF8_BOM)<<std::endl;
    ofs<<"Вывод wstr_UTF8(с перекодировкой):\t\t"<<utf8_encode(wstr_UTF8)<<std::endl;
    ofs<<"Вывод строки введенной с консоли:\t\t"<<str<<std::endl;
    
    std::cout<<std::endl;
    return 0;
}
Попутно, два вопроса:
-почему это выбрасывает исключение?
C++
1
std::wcout.imbue(std::locale("rus_rus.866"));
-можно ли сразу задать тип кодировки при создании файла?
Yandex
Объявления
28.05.2013, 22:12     Кодировки, вывод/ввод на консоль и в файл
Ответ Создать тему
Опции темы

Текущее время: 04:59. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru