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

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

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 21, средняя оценка - 4.76
Excogit8er
2 / 2 / 0
Регистрация: 23.10.2012
Сообщений: 66
26.11.2012, 13:43     Unicode, UTF-8 и ANSI в одном консольном приложении. Можно ли "на лету" конвертировать массив строк? #1
Всем доброго дня)

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

C++ Ошибка "ANSI C++ forbids implicit conversion from void* in initialization"
C++ Обработка .txt кодировка ANSI и UTF-8 (буква "я" в ANSI воспринимается как EOF)
Можно ли реализовать игру змейка в консольном приложении C++
C++ Массив шаблонов или как обратиться к элементам разного типа, хранящиеся в одном "списке" по индексу
C++ я задал произвольный текст длинной 5 строк, и допустим что я ввел 5 раз букву "П" , какой цикл нужно создать чтобы пометять букву "П" на букву "Р" ?
Как конвертировать Unicode в Ansi? C++
C++ Класс "Телефонная станция". Массив символов и массив строк - в чем разница?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
12079 / 6940 / 782
Регистрация: 27.09.2012
Сообщений: 17,216
Записей в блоге: 2
Завершенные тесты: 1
26.11.2012, 13:51     Unicode, UTF-8 и ANSI в одном консольном приложении. Можно ли "на лету" конвертировать массив строк? #2
Цитата Сообщение от Excogit8er Посмотреть сообщение
можно ли в консольном приложении работать с несколькими кодировками?
конечно можно.
Цитата Сообщение от Excogit8er Посмотреть сообщение
Можно ли (и сложно ли) реализовать такую конвертацию из кодировки в кодировку "на лету"?
Зависит от Вас, ибо только Вы решаете что и как считывать, конвертировать, записывать
Excogit8er
2 / 2 / 0
Регистрация: 23.10.2012
Сообщений: 66
26.11.2012, 14:03  [ТС]     Unicode, UTF-8 и ANSI в одном консольном приложении. Можно ли "на лету" конвертировать массив строк? #3
Цитата Сообщение от Croessmah Посмотреть сообщение
конечно можно.
Зависит от Вас, ибо только Вы решаете что и как считывать, конвертировать, записывать
Допустим, есть текстовый файлик в кодировке utf-8. Можно примерчик, как считать из него (той же getline) строку и конвертировать, скажем, в ANSI?
Герц
523 / 340 / 4
Регистрация: 05.11.2010
Сообщений: 1,077
Записей в блоге: 1
26.11.2012, 14:07     Unicode, UTF-8 и ANSI в одном консольном приложении. Можно ли "на лету" конвертировать массив строк? #4
Что за ANSI?
utf-8 читается в точности так же, как и любая другая кодировка - побайтно. Преобразовать utf-8 в utf-16 или utf-32 не сложно.
Excogit8er
2 / 2 / 0
Регистрация: 23.10.2012
Сообщений: 66
26.11.2012, 14:17  [ТС]     Unicode, UTF-8 и ANSI в одном консольном приложении. Можно ли "на лету" конвертировать массив строк? #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?
Герц
523 / 340 / 4
Регистрация: 05.11.2010
Сообщений: 1,077
Записей в блоге: 1
26.11.2012, 14:24     Unicode, UTF-8 и ANSI в одном консольном приложении. Можно ли "на лету" конвертировать массив строк? #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;
    }
ForEveR
Модератор
Эксперт С++
 Аватар для ForEveR
7933 / 4715 / 318
Регистрация: 24.06.2010
Сообщений: 10,525
Завершенные тесты: 3
26.11.2012, 14:41     Unicode, UTF-8 и ANSI в одном консольном приложении. Можно ли "на лету" конвертировать массив строк? #7
Excogit8er, boost::locale. http://www.boost.org/doc/libs/1_52_0...tml/index.html
BumerangSP
 Аватар для BumerangSP
4283 / 1405 / 121
Регистрация: 16.12.2010
Сообщений: 2,941
Записей в блоге: 3
26.11.2012, 14:55     Unicode, UTF-8 и ANSI в одном консольном приложении. Можно ли "на лету" конвертировать массив строк? #8
Excogit8er, можно влом пойти: не использовать никаких массивов байт и чего-то подобного, а создать пару массивов, в одном будут храниться ascii коды символов, а в другом сами символы. Т.е все это в пределах одной кодировки: списать таблицу какой-нибудь кодировки в массивы. Но это долго и муторно.
activnaya
 Аватар для activnaya
255 / 45 / 2
Регистрация: 24.11.2012
Сообщений: 466
26.11.2012, 15:10     Unicode, UTF-8 и ANSI в одном консольном приложении. Можно ли "на лету" конвертировать массив строк? #9
Цитата Сообщение от BumerangSP Посмотреть сообщение
в одном будут храниться ascii коды символов, а в другом сами символы
C++
1
std::cout << std::hex << (int)'A';
сам символ и есть свой код.
BumerangSP
 Аватар для BumerangSP
4283 / 1405 / 121
Регистрация: 16.12.2010
Сообщений: 2,941
Записей в блоге: 3
26.11.2012, 15:25     Unicode, UTF-8 и ANSI в одном консольном приложении. Можно ли "на лету" конвертировать массив строк? #10
Цитата Сообщение от activnaya Посмотреть сообщение
C++
1
std::cout << std::hex << (int)'A';
сам символ и есть свой код.
Суть не в этом, я просто как-то подобное еще на delphi делал, не помню уж.
-=ЮрА=-
Заблокирован
Автор FAQ
26.11.2012, 15:55     Unicode, UTF-8 и ANSI в одном консольном приложении. Можно ли "на лету" конвертировать массив строк? #11
Excogit8er, MultyByteToWindeChar в помощь тут есть код для копипаста
Создание файла в UTF-8 кодировке
Excogit8er
2 / 2 / 0
Регистрация: 23.10.2012
Сообщений: 66
26.11.2012, 19:00  [ТС]     Unicode, UTF-8 и ANSI в одном консольном приложении. Можно ли "на лету" конвертировать массив строк? #12
Цитата Сообщение от ForEveR Посмотреть сообщение
Спасибо, похоже что мощная штука и как раз для подобных задач. Почитаю примеры)

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

Добавлено через 3 минуты
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
Excogit8er, MultyByteToWindeChar в помощь тут есть код для копипаста
Создание файла в UTF-8 кодировке
О! А вот это вот то, что доктор прописал, именно что нужно - красивое решение задачи. Спасибо.
Сорри за ламерский вопрос, но ИЗ utf-8 в chcp 1251 этой же функцией можно сконвертировать?
Потому что в примере наоборот - 1251 в utf-8.
alsav22
5284 / 4803 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
26.11.2012, 19:18     Unicode, UTF-8 и ANSI в одном консольном приложении. Можно ли "на лету" конвертировать массив строк? #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;
}
Excogit8er
2 / 2 / 0
Регистрация: 23.10.2012
Сообщений: 66
26.11.2012, 19:34  [ТС]     Unicode, UTF-8 и ANSI в одном консольном приложении. Можно ли "на лету" конвертировать массив строк? #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 работает в консольных приложениях без проблем? Я видел её упоминание уже, но думал, что это только для "оконных" вариантов.
alsav22
5284 / 4803 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
26.11.2012, 19:44     Unicode, UTF-8 и ANSI в одном консольном приложении. Можно ли "на лету" конвертировать массив строк? #15
Цитата в 14 посте не соотвутсвует коду в 13.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.11.2012, 20:03     Unicode, UTF-8 и ANSI в одном консольном приложении. Можно ли "на лету" конвертировать массив строк?
Еще ссылки по теме:

C++ Классы "Бинарное дерево" и "Узел" в одном приложении
Заполнять массив строк пока не будет введено слово "stop". C++
C++ Класс "Одномерный массив строк фиксированной длины"
Работа с памятью: можно ли в массив объектов с полем типа "Родитель", вписать объекты с полем типа "Потомок" C++
C++ Можно ли в консольном приложении вывести 25 цифр после запятой?

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

Или воспользуйтесь поиском по форуму:
Excogit8er
2 / 2 / 0
Регистрация: 23.10.2012
Сообщений: 66
26.11.2012, 20:03  [ТС]     Unicode, UTF-8 и ANSI в одном консольном приложении. Можно ли "на лету" конвертировать массив строк? #16
Цитата Сообщение от alsav22 Посмотреть сообщение
Цитата в 14 посте не соотвутсвует коду в 13.
Да, я хотел отредактировать, но прошло больше 5 минут. Собственно, вопрос про вот этот фрагмент кода:

C++
1
2
3
4
5
 wcout.imbue(locale("rus_rus.866")); //включаем другую кодировку.
    //setlocale(0, "rus_rus.866"); // или так.
    wcout << wbuff << endl; // выводим содержимое буфера wchar_t
    
    setlocale(0, ".1251"); // вернули кодировку.
Я просто не очень понял, для чего ещё и rus_rus.866 нужна. Можно ли вот так?
C++
1
2
3
 wcout.imbue(locale(0, ".1251")); // возвращаем кодировку.
ostream outfile ("1251.txt");
outfile << wbuff << endl; // выводим содержимое буфера wchar_t в файл
Yandex
Объявления
26.11.2012, 20:03     Unicode, UTF-8 и ANSI в одном консольном приложении. Можно ли "на лету" конвертировать массив строк?
Ответ Создать тему
Опции темы

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