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

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 18, средняя оценка - 4.67
gore-lykovoe
32 / 32 / 1
Регистрация: 04.04.2010
Сообщений: 414
#1

Какой самый универсальный способ считать UTF-8 текст на кириллице из файла? - C++

04.09.2013, 12:00. Просмотров 2676. Ответов 27
Метки нет (Все метки)

Считать UTF-8 текст на кириллице из файла? Нашел много способов, но все они страшные до безобразия. Также кажутся не оптимальными.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
04.09.2013, 12:00
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Какой самый универсальный способ считать UTF-8 текст на кириллице из файла? (C++):

Считать квадратную матрицу. Какой самый быстрый способ это сделать? - C++
Какие самые быстрые способы считывания в с++? Пример : мне надо считать квадратную матрицу. Какой самый быстрый способ это сделать?

Считать текст из файла с кодировкой utf-16 LE - C++
Возникла кое-какая проблема. У меня имеется xml файл, в кодировке UTF-16 LE с определенным содержимым. На данный момент мне нужно получить...

Считать utf-8 из файла - C++
Доброго времени суток. Задача следующая. Есть текстовый файл - словарь в utf-8 кодировке. Слова разделены переводом строки. Считываю...

Как правильно считать текст из файла? Весь текст, со всеми знаками, пробелами - C++
подскажите, чет затупил как правильно считать текст из файла(весь текст со всеми знаками пробелами и т.д.), чтобы поработать с этим текстом...

Определить, какой сначала был день самый тёплый или самый холодный? - C++
Динамическая память. В массив занесена информация о температуре за неделю. Определить, какой сначала был день самый тёплый или самый...

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

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
gromo
370 / 269 / 24
Регистрация: 04.09.2009
Сообщений: 1,214
04.09.2013, 23:44 #16
Цитата Сообщение от gore-lykovoe Посмотреть сообщение
Попробуйте такой вариант.
Также кракозябры вместо кириллицы...
я забыл просто... вы system("chcp 1251"); к этому новому варианту дописывали? Windows у вас русская или на английском языке? Если на английском, то скачайте русскую локаль через центр обновления и поставьте её.

как видно из скриншота все работает. И на Windows тоже должно
Миниатюры
Какой самый универсальный способ считать UTF-8 текст на кириллице из файла?   Какой самый универсальный способ считать UTF-8 текст на кириллице из файла?  
DiffEreD
1430 / 767 / 95
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
05.09.2013, 00:12 #17
Когдато експерементировал с файлами в кодировке UTF8, - вот старый код нарыл, может поможет:
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
#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, "");
 
    std::ifstream ifs_UTF8("D:/file_UTF8.txt");
 
    std::string str_UTF8;
    std::getline(ifs_UTF8, str_UTF8);
    std::wstring wstr_UTF8(utf8_decode(str_UTF8));
 
    std::wcout<<"Вывод wstr_UTF8:\t"<<wstr_UTF8<<std::endl;
 
    //############################################################
 
    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;
 
    //############################################################
 
    //выводим в файл
    std::ofstream ofs("D:/results.txt", std::ios::ate); //файл будет в кодировке ANSI
 
    ofs<<"Вывод wstr_UTF8(с перекодировкой):\t\t"<<utf8_encode(wstr_UTF8)<<std::endl;
    ofs<<"Вывод строки введенной с консоли:\t\t"<<str<<std::endl;
 
    std::cout<<"\nГотово"<<std::endl;
    return 0;
}
alsav22
5417 / 4813 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
05.09.2013, 00:19 #18
Цитата Сообщение от gromo Посмотреть сообщение
И на Windows тоже должно
Уверены?
gore-lykovoe
32 / 32 / 1
Регистрация: 04.04.2010
Сообщений: 414
05.09.2013, 00:23  [ТС] #19
Цитата Сообщение от gromo Посмотреть сообщение
я забыл просто... вы system("chcp 1251"); к этому новому варианту дописывали? Windows у вас русская или на английском языке? Если на английском, то скачайте русскую локаль через центр обновления и поставьте её.
нет, скопировал чисто ваш вариант, но пробывал и дописывать, не помогает, винда русская
Цитата Сообщение от gromo Посмотреть сообщение
И на Windows тоже должно
обычно даже на одной ОС в разных IDE может по-разному работать...

Добавлено через 2 минуты
Цитата Сообщение от DiffEreD Посмотреть сообщение
вот старый код нарыл, может поможет:
Поможет, но это "экспериментальный код". Я видел способы чтения UTF из файла через расширенные символы, но мне кажется этот способ слишком костыльным и проблемным, хочется увидеть код, который используется повсеместно, проблема же часто встречающаяся.
alsav22
5417 / 4813 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
05.09.2013, 00:26 #20
Цитата Сообщение от gore-lykovoe Посмотреть сообщение
хочется увидеть код, который используется повсеместно, проблема же часто встречающаяся.
Цитата Сообщение от gore-lykovoe Посмотреть сообщение
Нашел много способов, но все они страшные до безобразия.
То чего вам хочется, не увидите.
gore-lykovoe
32 / 32 / 1
Регистрация: 04.04.2010
Сообщений: 414
05.09.2013, 00:31  [ТС] #21
Цитата Сообщение от alsav22 Посмотреть сообщение
То чего вам хочется, не увидите.
Ну если заставить работать данный код на винде, то он вполне устроит меня...
alsav22
5417 / 4813 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
05.09.2013, 00:39 #22
Цитата Сообщение от gore-lykovoe Посмотреть сообщение
Ну если заставить работать данный код на винде, то он вполне устроит меня...
В том-то и дело, что навряд ли... Я так понял, у того, кто предложил - Linux?

Добавлено через 2 минуты
Цитата Сообщение от gore-lykovoe Посмотреть сообщение
Нашел много способов,
Если бы был очень простой, то зачем тогда этих много? Все бы очень простым пользовались
gromo
370 / 269 / 24
Регистрация: 04.09.2009
Сообщений: 1,214
05.09.2013, 00:46 #23
Цитата Сообщение от alsav22 Посмотреть сообщение
Уверены?
не могу утверждать на 100%, но по-моему здесь нет никакого ОС-зависимого кода. Хотя... я не уверен. (уже)
alsav22
5417 / 4813 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
05.09.2013, 01:02 #24
Цитата Сообщение от gromo Посмотреть сообщение
но по-моему здесь нет никакого ОС-зависимого кода.
Дело не в коде, а в разных кодировках консоли.
gore-lykovoe
32 / 32 / 1
Регистрация: 04.04.2010
Сообщений: 414
05.09.2013, 01:06  [ТС] #25
Цитата Сообщение от alsav22 Посмотреть сообщение
Дело не в коде, а в разных кодировках консоли.
вот-вот, в cmd - oem 866 вроде, а в терминале юникс машин как-раз utf, поэтому там нормально и выводит
alsav22
5417 / 4813 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
05.09.2013, 01:09 #26
Этот, конечно, видели?
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
#include <iostream>
#include <fstream>
#include <Windows.h>
using namespace std;
 
int main()
{
    setlocale(0, ".1251"); //включили кодировку.
    //SetConsoleCP (1251); 
    //SetConsoleOutputCP (1251); // или так.
    
    char buff[5000];
    wchar_t wbuff[5000];
    
    ifstream f("1.txt");
    if (!f) cout << "Error!" << endl;
    else
    {
        int i = 0;
        while (f.get(buff[i])) ++i;
        
        MultiByteToWideChar(CP_UTF8, 0, buff, 5000, wbuff, 5000); //из буфера char в буфер wchar_t .
        setlocale(0, "rus_rus.866"); //включаем другую кодировку.
        wcout << wbuff << endl; // выводим содержимое буфера wchar_t
    
        setlocale(0, ".1251"); // вернули кодировку.
    }
    
    system("pause");
    return 0;
}
Миниатюры
Какой самый универсальный способ считать UTF-8 текст на кириллице из файла?  
gore-lykovoe
32 / 32 / 1
Регистрация: 04.04.2010
Сообщений: 414
05.09.2013, 01:47  [ТС] #27
Цитата Сообщение от alsav22 Посмотреть сообщение
Этот, конечно, видели?
Это не видел. Такой вариант нравится. Спасибо.
alsav22
5417 / 4813 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
05.09.2013, 03:27 #28
Нужно только учитывать, что некоторые программы (в частности блокнот) вставляют в начало файла маркер кодировки BOM (для UTF-8 три байта). Поэтому сначала нужно проверить, имеет ли файл этот маркер, и если имеет, то исключить первые три байта из записи в буфер.
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
#include <iostream>
#include <fstream>
#include <Windows.h>
using namespace std;
 
int main()
{
    //setlocale(0, ".1251"); //включили кодировку.
    SetConsoleCP (1251); 
    SetConsoleOutputCP (1251); // или так.
    
    char buff[5000];
    wchar_t wbuff[5000];
    
    ifstream f("111.txt", ios::binary);
    if (!f) cout << "Error!" << endl;
    else
    {
        f.get(buff, 4); // считали первые три байта
        
        if ((unsigned char)buff[0] == 0xEF && (unsigned char)buff[1] == 0xBB && (unsigned char)buff[2] == 0xBF); // если BOM есть, то читаем в буфер c позции за BOM
        else  f.seekg(0); // если BOM нет, то курсор в начало файла
        
        int i = 0;
        while (f.get(buff[i])) ++i;
        f.close();
        
        MultiByteToWideChar(CP_UTF8, 0, buff, 5000, wbuff, 5000); //из буфера char в буфер wchar_t .
        setlocale(0, "rus_rus.866"); //включаем другую кодировку.
        wcout << wbuff << endl; // выводим содержимое буфера wchar_t
    
        setlocale(0, ".1251"); // вернули кодировку.
    }
    cout << endl;
    system("pause");
    return 0;
}
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.09.2013, 03:27
Привет! Вот еще темы с ответами:

Считать текст из файла - C++
Как можно считать текст из файла?? ifstream fin(&quot;test.txt&quot;, ios::in|ios::nocreate ); if (!fin) {cout&lt;&lt;&quot;ERROR! &quot;&lt;&lt;endl; return 1;} ...

Как считать текст из файла? - C++
Подскажите, со считыванием из файла, а то добавил а обратно считать не могу, более подробно в комментакиях кода... Ну или с кодом для...

Как считать текст с файла ? - C++
Как считать текст с файла (например .txt) а потом в другой пустой файл записать текст с первого документа?

Как считать текст из файла в С++? - C++
Подскажите пожалуйста, как считать текст из файла в массив типа char в С++? Заранее спасибо!


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
05.09.2013, 03:27
Ответ Создать тему
Опции темы

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