Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 21, средняя оценка - 4.76
Excogit8er
2 / 2 / 0
Регистрация: 23.10.2012
Сообщений: 66
Завершенные тесты: 1
#1

Unicode, UTF-8 и ANSI в одном консольном приложении. Можно ли "на лету" конвертировать массив строк? - C++

26.11.2012, 13:43. Просмотров 3022. Ответов 15
Метки нет (Все метки)

Всем доброго дня)

Подскажите такую весчь: можно ли в консольном приложении работать с несколькими кодировками? Нужно считать файлик в кодировке UTF-8 (в массив строк), далее конвертировать его в ANSI (чтобы проще было парсить текст) и измененный текст в кодировке UNICODE записать в другой файл. Именно в обычном консольном С++ приложении, не С++/CLI и т.д. Можно ли (и сложно ли) реализовать такую конвертацию из кодировки в кодировку "на лету"?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.11.2012, 13:43
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Unicode, UTF-8 и ANSI в одном консольном приложении. Можно ли "на лету" конвертировать массив строк? (C++):

Обработка .txt кодировка ANSI и UTF-8 (буква "я" в ANSI воспринимается как EOF) - C++
Есть следующий кусок кода: FILE* fp = fopen("G:\OPND1.txt", "r"); if (fp!=NULL) // если файл удалось открыть { while((ch =...

Как конвертировать Unicode в Ansi? - C++
Я написал свою функцию конвертирования из Unicode в Ansi, но она не правильно кодирует символы русского языка. Как такое исправить? ...

Классы "Бинарное дерево" и "Узел" в одном приложении - C++
Компилятор разбушевался((( Пробовала сделать вместо одного класса два класса(Дерево и узел). Сделала один класс дружественный другому. Но...

В зависимости от времени года "весна", "лето", "осень", "зима" определить погоду "тепло", "жарко", "холодно", "очень холодно" - C++
В зависимости от времени года "весна", "лето", "осень", "зима" определить погоду "тепло", "жарко", "холодно", "очень холодно". Я так...

Массив шаблонов или как обратиться к элементам разного типа, хранящиеся в одном "списке" по индексу - C++
Собственно, вот такой вот вопрос. Очень нужно решение. Спасибо.

Работа с памятью: можно ли в массив объектов с полем типа "Родитель", вписать объекты с полем типа "Потомок" - C++
Здравствуйте. Предположим, что у нас есть массив из структур в которых находиться класс Item и число Count. Можно ли на место Item записать...

15
Croessmah
Ушел
Эксперт CЭксперт С++
13557 / 7707 / 872
Регистрация: 27.09.2012
Сообщений: 18,996
Записей в блоге: 3
Завершенные тесты: 1
26.11.2012, 13:51 #2
Цитата Сообщение от Excogit8er Посмотреть сообщение
можно ли в консольном приложении работать с несколькими кодировками?
конечно можно.
Цитата Сообщение от Excogit8er Посмотреть сообщение
Можно ли (и сложно ли) реализовать такую конвертацию из кодировки в кодировку "на лету"?
Зависит от Вас, ибо только Вы решаете что и как считывать, конвертировать, записывать
0
Excogit8er
2 / 2 / 0
Регистрация: 23.10.2012
Сообщений: 66
Завершенные тесты: 1
26.11.2012, 14:03  [ТС] #3
Цитата Сообщение от Croessmah Посмотреть сообщение
конечно можно.
Зависит от Вас, ибо только Вы решаете что и как считывать, конвертировать, записывать
Допустим, есть текстовый файлик в кодировке utf-8. Можно примерчик, как считать из него (той же getline) строку и конвертировать, скажем, в ANSI?
0
Герц
524 / 341 / 4
Регистрация: 05.11.2010
Сообщений: 1,077
Записей в блоге: 1
26.11.2012, 14:07 #4
Что за ANSI?
utf-8 читается в точности так же, как и любая другая кодировка - побайтно. Преобразовать utf-8 в utf-16 или utf-32 не сложно.
0
Excogit8er
2 / 2 / 0
Регистрация: 23.10.2012
Сообщений: 66
Завершенные тесты: 1
26.11.2012, 14:17  [ТС] #5
Цитата Сообщение от Герц Посмотреть сообщение
Что за ANSI?
utf-8 читается в точности так же, как и любая другая кодировка - побайтно. Преобразовать utf-8 в utf-16 или utf-32 не сложно.
ANSI 1251. И все-таки, что значит "не сложно"? Например, вот я считал строку в формате utf8 в string.

fstream infile ("utf8.txt", ios_base::in);
string str;
while (infile.good()) // while input good and not at EOF
{infile.getline (str, '\n');
...

Как эту строку преобразовать в тот же ANSI 1251? В UNICODE?
0
Герц
524 / 341 / 4
Регистрация: 05.11.2010
Сообщений: 1,077
Записей в блоге: 1
26.11.2012, 14:24 #6
Вот преобразование utf-8 в utf-32:
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
    //  UTF-8 -> UTF-32
    utf32string utf8ToUtf32( const utf8string& input )
    {
        //  Current state - none or matching 2-3-4 byte sequence
        enum {
            None,
            Two,
            Three,
            Four
        };
 
        utf32string wide;
        //  Unicode standard version 5.2 recommends to replace each maximal ill-formed subsequence by
        //  a single U+FFFD
        int32_t error = 0xfffd;
 
        int state = None;
        int32_t n;
        
        std::size_t length = input.size();
        for ( int i = 0; i < length; ++i ) {
            char c = input[ i ];
 
            if ( state == None ) {
                //  0xxx xxxx
                if ( ( c & 0x80 ) == 0 ) {
                    wide += c;
                } else {
                    //  110y yyyy   10xx xxxxx
                    if ( ( c & 0x70 ) == 0xc0 ) {
                        n = c & 0x1f;
                        state = Two;
                    } else {
                        //  1110 zzzz   10yy yyyy   10xx xxxx
                        if ( ( c & 0xf0 ) == 0xe0) {
                            n = c & 0x0f;
                            state = Three;
                        } else {
                            //  1111 0uuu   10uu zzzz   10yy yyyy   10xx xxxx
                            if ( ( c & 0xf8 ) == 0xf0 ) {
                                n = c & 0x07;
                                state = Four;
                            } else {
                                wide += error;
                                state = None;
                            }
                        }
                    }
                }
            } else {
                if ( ( c & 0xc0 ) == 0x80 ) {
                    n = ( n << 6 ) | ( c & 0x3f );
                    if ( --state == 0 ) {
                        wide += n;
                    }
                } else {
                    wide += error;
                    state = None;
                    //  Start matching subsequences from current faulty symbol
                    i--;
                }
            }
        }
 
        return wide;
    }
1
ForEveR
В астрале
Эксперт С++
7983 / 4742 / 321
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
26.11.2012, 14:41 #7
Excogit8er, boost::locale. http://www.boost.org/doc/libs/1_52_0/libs/locale/doc/html/index.html
1
BumerangSP
4287 / 1409 / 121
Регистрация: 16.12.2010
Сообщений: 2,941
Записей в блоге: 3
26.11.2012, 14:55 #8
Excogit8er, можно влом пойти: не использовать никаких массивов байт и чего-то подобного, а создать пару массивов, в одном будут храниться ascii коды символов, а в другом сами символы. Т.е все это в пределах одной кодировки: списать таблицу какой-нибудь кодировки в массивы. Но это долго и муторно.
0
activnaya
255 / 45 / 2
Регистрация: 24.11.2012
Сообщений: 466
26.11.2012, 15:10 #9
Цитата Сообщение от BumerangSP Посмотреть сообщение
в одном будут храниться ascii коды символов, а в другом сами символы
C++
1
std::cout << std::hex << (int)'A';
сам символ и есть свой код.
0
BumerangSP
4287 / 1409 / 121
Регистрация: 16.12.2010
Сообщений: 2,941
Записей в блоге: 3
26.11.2012, 15:25 #10
Цитата Сообщение от activnaya Посмотреть сообщение
C++
1
std::cout << std::hex << (int)'A';
сам символ и есть свой код.
Суть не в этом, я просто как-то подобное еще на delphi делал, не помню уж.
0
-=ЮрА=-
Заблокирован
Автор FAQ
26.11.2012, 15:55 #11
Excogit8er, MultyByteToWindeChar в помощь тут есть код для копипаста
Создание файла в UTF-8 кодировке
1
Excogit8er
2 / 2 / 0
Регистрация: 23.10.2012
Сообщений: 66
Завершенные тесты: 1
26.11.2012, 19:00  [ТС] #12
Цитата Сообщение от ForEveR Посмотреть сообщение
Спасибо, похоже что мощная штука и как раз для подобных задач. Почитаю примеры)

Добавлено через 2 минуты
Цитата Сообщение от BumerangSP Посмотреть сообщение
Excogit8er, можно влом пойти: не использовать никаких массивов байт и чего-то подобного, а создать пару массивов, в одном будут храниться ascii коды символов, а в другом сами символы. Т.е все это в пределах одной кодировки: списать таблицу какой-нибудь кодировки в массивы. Но это долго и муторно.
Хехе, ну нет, это по ходу путь настоящего джедая, я пока что к подобным экзерсисам не готов ))
Мне бы что-нить потривиальней, типа там вызвал функцию и конвертировал.

Добавлено через 3 минуты
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
Excogit8er, MultyByteToWindeChar в помощь тут есть код для копипаста
Создание файла в UTF-8 кодировке
О! А вот это вот то, что доктор прописал, именно что нужно - красивое решение задачи. Спасибо.
Сорри за ламерский вопрос, но ИЗ utf-8 в chcp 1251 этой же функцией можно сконвертировать?
Потому что в примере наоборот - 1251 в utf-8.
0
alsav22
5428 / 4823 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
26.11.2012, 19:18 #13
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
#include <iostream>
#include <fstream>
#include <Windows.h>
using namespace std;
 
int main()
{
    setlocale(0, ".1251"); //включили кодировку
    //SetConsoleCP (1251); 
    //SetConsoleOutputCP (1251); // или так.
    
    char buff[500];
    wchar_t wbuff[500];
 
    ifstream f("upload.txt");
    
    f.getline(buff, 500); // в буффер char из файла UTF-8.
    
    MultiByteToWideChar(CP_UTF8, 0, buff, 500, wbuff, 500); //из буфера char в буфер wchar_t .
    wcout.imbue(locale("rus_rus.866")); //включаем другую кодировку.
    //setlocale(0, "rus_rus.866"); // или так.
    wcout << wbuff << endl; // выводим содержимое буфера wchar_t
    
    setlocale(0, ".1251"); // вернули кодировку.
    
    system("pause");
    return 0;
}
1
Excogit8er
2 / 2 / 0
Регистрация: 23.10.2012
Сообщений: 66
Завершенные тесты: 1
26.11.2012, 19:34  [ТС] #14
Цитата Сообщение от alsav22 Посмотреть сообщение
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
#include <iostream>
#include <fstream>
#include <Windows.h>
using namespace std;
 
int main()
{
    setlocale(0, ".1251"); //включили кодировку
    //SetConsoleCP (1251); 
    //SetConsoleOutputCP (1251); // или так.
    
    char buff[500];
    wchar_t wbuff[500];
 
    ifstream f("upload.txt");
    
    f.getline(buff, 500); // в буффер char из файла UTF-8.
    
    MultiByteToWideChar(CP_UTF8, 0, buff, 500, wbuff, 500); //из буфера char в буфер wchar_t .
    wcout.imbue(locale("rus_rus.866")); //включаем другую кодировку.
    //setlocale(0, "rus_rus.866"); // или так.
    wcout << wbuff << endl; // выводим содержимое буфера wchar_t
    
    wcout.imbue(locale("rus_rus.866")); //включаем другую кодировку.
    
    system("pause");
    return 0;
}
Красиво, что сказать. Thanx! Причем все просто и ясно, кроме одного момента:

wcout.imbue(locale("rus_rus.866")); //включаем другую кодировку.

А для чего нужна это строка? Ну, т.е. понятно, что включаем другую кодировку, но почему не сразу эту:

setlocale(0, ".1251"); // вернули кодировку.

И ещё: MultiByteToWideChar работает в консольных приложениях без проблем? Я видел её упоминание уже, но думал, что это только для "оконных" вариантов.
0
alsav22
5428 / 4823 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
26.11.2012, 19:44 #15
Цитата в 14 посте не соотвутсвует коду в 13.
0
26.11.2012, 19:44
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.11.2012, 19:44
Привет! Вот еще темы с ответами:

Класс "Телефонная станция". Массив символов и массив строк - в чем разница? - C++
Всем привет. Не могу исправить в программе пункт корректировки. Весь проект прикрепляю к сообщению. ...

Можно ли реализовать игру змейка в консольном приложении - C++
можно ли реализовать игру змейка в консольном приложении??? обдумывая решения столкнулся с проблемами вывода змейки при поворотах... Можете...

я задал произвольный текст длинной 5 строк, и допустим что я ввел 5 раз букву "П" , какой цикл нужно создать чтобы пометять букву "П" на букву "Р" ? - C++
я задал произвольный текст длинной 5 строк, и допустим что я ввел 5 раз букву &quot;П&quot; , какой цикл нужно создать чтобы пометять букву &quot;П&quot; на...

Можно ли в консольном приложении вывести 25 цифр после запятой? - C++
Можно ли в консольном приложении вывести цифр 25 после запятой? cout выводит только цифр 6, а setw(n) только сдвигает число в конец строки


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.