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

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

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 18, средняя оценка - 4.67
gore-lykovoe
 Аватар для gore-lykovoe
31 / 31 / 1
Регистрация: 04.04.2010
Сообщений: 414
04.09.2013, 12:00     Какой самый универсальный способ считать UTF-8 текст на кириллице из файла? #1
Считать UTF-8 текст на кириллице из файла? Нашел много способов, но все они страшные до безобразия. Также кажутся не оптимальными.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
AntonChik
1083 / 581 / 21
Регистрация: 11.11.2008
Сообщений: 1,544
04.09.2013, 12:11     Какой самый универсальный способ считать UTF-8 текст на кириллице из файла? #2
а в чем собственно должна заключаться универсальность?
gore-lykovoe
 Аватар для gore-lykovoe
31 / 31 / 1
Регистрация: 04.04.2010
Сообщений: 414
04.09.2013, 12:15  [ТС]     Какой самый универсальный способ считать UTF-8 текст на кириллице из файла? #3
Цитата Сообщение от AntonChik Посмотреть сообщение
а в чем собственно должна заключаться универсальность?
В использовании только средств С++, в ктраткости кода, в расходовании ресурсов, в удобочитаемости, etc.

Хотя да, вы правы, я хотел сказать "оптимальный способ"...
zer0mail
2220 / 1903 / 192
Регистрация: 03.07.2012
Сообщений: 6,811
Записей в блоге: 1
04.09.2013, 13:10     Какой самый универсальный способ считать UTF-8 текст на кириллице из файла? #4
Сначала надо понять, как прочитанные данные будут обрабатываться и храниться в памяти.
А самый универсальный - чтение бинарного файла в байтовый массив
gore-lykovoe
 Аватар для gore-lykovoe
31 / 31 / 1
Регистрация: 04.04.2010
Сообщений: 414
04.09.2013, 13:14  [ТС]     Какой самый универсальный способ считать UTF-8 текст на кириллице из файла? #5
Цитата Сообщение от zer0mail Посмотреть сообщение
Сначала надо понять, как прочитанные данные будут обрабатываться и храниться в памяти.
Допустим одна строка с помощью getline помещается в string и сразу выводится.
Герц
523 / 340 / 4
Регистрация: 05.11.2010
Сообщений: 1,077
Записей в блоге: 1
04.09.2013, 14:18     Какой самый универсальный способ считать UTF-8 текст на кириллице из файла? #6
C++
1
2
3
4
5
    auto contents = [] (const std::string& fileName)->std::string {
        std::ifstream in(fileName, std::ios::binary);
        return std::string(std::istreambuf_iterator<char>(in),
            std::istreambuf_iterator<char>());
    }("utf-8.txt");
gromo
 Аватар для gromo
367 / 266 / 24
Регистрация: 04.09.2009
Сообщений: 1,214
04.09.2013, 14:41     Какой самый универсальный способ считать UTF-8 текст на кириллице из файла? #7
Цитата Сообщение от Герц Посмотреть сообщение
auto contents = [] (const std::string& fileName)->std::string {
* * * * std::ifstream in(fileName, std::ios::binary);
* * * * return std::string(std::istreambuf_iterator<char>(in),
* * * * * * std::istreambuf_iterator<char>());
* * }("utf-8.txt");
C++
1
2
3
4
5
6
7
8
auto contents = [] (const std::string& fileName)->std::string {
        std::ifstream in(fileName, std::ios::binary);
 
        return std::string(std::istreambuf_iterator<char>(in),
            std::istreambuf_iterator<char>());
    };
 
    std::cout <<contents(std::string("utf-8.txt")) <<std::endl;
Вот так работает.
Герц, это вы опечатались или это еще какая-то фича с++11 при задании аргумента-файла?
ForEveR
Модератор
Эксперт С++
 Аватар для ForEveR
7934 / 4716 / 318
Регистрация: 24.06.2010
Сообщений: 10,525
Завершенные тесты: 3
04.09.2013, 14:46     Какой самый универсальный способ считать UTF-8 текст на кириллице из файла? #8
gromo, Все там правильно.
Просто лямбда определяется и сразу же вызывается.
Герц
523 / 340 / 4
Регистрация: 05.11.2010
Сообщений: 1,077
Записей в блоге: 1
04.09.2013, 15:57     Какой самый универсальный способ считать UTF-8 текст на кириллице из файла? #9
Да, сделано исключительное ради ограничения области видимости std::ifstream in.
Nameless One
Эксперт С++
 Аватар для Nameless One
5759 / 3408 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
04.09.2013, 16:32     Какой самый универсальный способ считать UTF-8 текст на кириллице из файла? #10
Герц, но зачем лямбду-то использовать? В C++ и так блочная область видимости, это же не Javascript.
Герц
523 / 340 / 4
Регистрация: 05.11.2010
Сообщений: 1,077
Записей в блоге: 1
04.09.2013, 17:26     Какой самый универсальный способ считать UTF-8 текст на кириллице из файла? #11
Уединенный блок выглядит коряво.
Nameless One
Эксперт С++
 Аватар для Nameless One
5759 / 3408 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
04.09.2013, 17:29     Какой самый универсальный способ считать UTF-8 текст на кириллице из файла? #12
Герц, лямбда там, где она совсем не нужна, выглядит ещё более коряво.
gore-lykovoe
 Аватар для gore-lykovoe
31 / 31 / 1
Регистрация: 04.04.2010
Сообщений: 414
04.09.2013, 20:38  [ТС]     Какой самый универсальный способ считать UTF-8 текст на кириллице из файла? #13
Цитата Сообщение от gromo Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
auto contents = [] (const std::string& fileName)->std::string {
        std::ifstream in(fileName, std::ios::binary);
 
        return std::string(std::istreambuf_iterator<char>(in),
            std::istreambuf_iterator<char>());
    };
 
    std::cout <<contents(std::string("utf-8.txt")) <<std::endl;
Вот так работает.
Кириллица отображается кракозябрами по-прежнему...
Исходный код:
Кликните здесь для просмотра всего текста
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
#include <iostream>
#include <fstream>
#include <string>
 
int main(int argc, char *argv[])
{
    system("chcp 1251");
    //setlocale(LC_ALL, ".1251");
    for (int i=1; i<argc; i++)
    {
        auto contents = [] (const std::string& fileName)->std::string
        {
            std::ifstream in(fileName, std::ios::binary);
            return std::string(std::istreambuf_iterator<char>(in),
                std::istreambuf_iterator<char>());
        };
        std::cout <<contents(std::string(argv[i])) <<std::endl;
        /*std::ifstream file(argv[i]);
        if (!file.is_open())
            std::cout<<argv[i]<<": Файла с данным именем не существует\n";
        else
        {
            std::cout<<argv[i]<<std::endl;
            while (! file.eof() )
            {
                
                std::string buf;
                getline (file, buf);
                std::cout<<buf<<std::endl;
            }
        }*/
    }
    std::cout<<std::endl;
    std::system("pause");
    return 0;
}

visual studio 2012
Прикрепил сам текстовый файл
Вложения
Тип файла: txt 1.txt (629 байт, 9 просмотров)
gromo
 Аватар для gromo
367 / 266 / 24
Регистрация: 04.09.2009
Сообщений: 1,214
04.09.2013, 22:24     Какой самый универсальный способ считать UTF-8 текст на кириллице из файла? #14
Попробуйте такой вариант. Вы шрифт на Lucida Console сменили в cmd.exe ?
Я не знаю, как там в VStudio, но пишут, что лямбды должен поддерживать.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <fstream>
#include <string>
int main(int argc, char* argv[])
{
    for(int i = 1; i < argc; ++i)
        std::cout<< [] (const std::string& fileName)->std::string {
            std::ifstream in(fileName, std::ios_base::binary);
 
            return std::string(std::istreambuf_iterator<char>(in),
                std::istreambuf_iterator<char>());
        }(argv[i]);
    return 0;
}
проверил на вашем файле 1.txt -- все работает. Пути к файлам задайте абсолютные (на всякий случай)
gore-lykovoe
 Аватар для gore-lykovoe
31 / 31 / 1
Регистрация: 04.04.2010
Сообщений: 414
04.09.2013, 23:03  [ТС]     Какой самый универсальный способ считать UTF-8 текст на кириллице из файла? #15
Цитата Сообщение от gromo Посмотреть сообщение
Вы шрифт на Lucida Console сменили в cmd.exe ?
Да, конечно.
Цитата Сообщение от gromo Посмотреть сообщение
Попробуйте такой вариант.
Также кракозябры вместо кириллицы...
gromo
 Аватар для gromo
367 / 266 / 24
Регистрация: 04.09.2009
Сообщений: 1,214
04.09.2013, 23:44     Какой самый универсальный способ считать UTF-8 текст на кириллице из файла? #16
Цитата Сообщение от gore-lykovoe Посмотреть сообщение
Попробуйте такой вариант.
Также кракозябры вместо кириллицы...
я забыл просто... вы system("chcp 1251"); к этому новому варианту дописывали? Windows у вас русская или на английском языке? Если на английском, то скачайте русскую локаль через центр обновления и поставьте её.

как видно из скриншота все работает. И на Windows тоже должно
Миниатюры
Какой самый универсальный способ считать UTF-8 текст на кириллице из файла?   Какой самый универсальный способ считать UTF-8 текст на кириллице из файла?  
DiffEreD
 Аватар для DiffEreD
1424 / 761 / 95
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
05.09.2013, 00:12     Какой самый универсальный способ считать UTF-8 текст на кириллице из файла? #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
5284 / 4803 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
05.09.2013, 00:19     Какой самый универсальный способ считать UTF-8 текст на кириллице из файла? #18
Цитата Сообщение от gromo Посмотреть сообщение
И на Windows тоже должно
Уверены?
gore-lykovoe
 Аватар для gore-lykovoe
31 / 31 / 1
Регистрация: 04.04.2010
Сообщений: 414
05.09.2013, 00:23  [ТС]     Какой самый универсальный способ считать UTF-8 текст на кириллице из файла? #19
Цитата Сообщение от gromo Посмотреть сообщение
я забыл просто... вы system("chcp 1251"); к этому новому варианту дописывали? Windows у вас русская или на английском языке? Если на английском, то скачайте русскую локаль через центр обновления и поставьте её.
нет, скопировал чисто ваш вариант, но пробывал и дописывать, не помогает, винда русская
Цитата Сообщение от gromo Посмотреть сообщение
И на Windows тоже должно
обычно даже на одной ОС в разных IDE может по-разному работать...

Добавлено через 2 минуты
Цитата Сообщение от DiffEreD Посмотреть сообщение
вот старый код нарыл, может поможет:
Поможет, но это "экспериментальный код". Я видел способы чтения UTF из файла через расширенные символы, но мне кажется этот способ слишком костыльным и проблемным, хочется увидеть код, который используется повсеместно, проблема же часто встречающаяся.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.09.2013, 00:26     Какой самый универсальный способ считать UTF-8 текст на кириллице из файла?
Еще ссылки по теме:

Как считать текст из файла? C++
C++ Считать квадратную матрицу. Какой самый быстрый способ это сделать?
C++ Определить, какой сначала был день самый тёплый или самый холодный?
Считать utf-8 из файла C++
Считать текст из файла с кодировкой utf-16 LE C++

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

Или воспользуйтесь поиском по форуму:
alsav22
5284 / 4803 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
05.09.2013, 00:26     Какой самый универсальный способ считать UTF-8 текст на кириллице из файла? #20
Цитата Сообщение от gore-lykovoe Посмотреть сообщение
хочется увидеть код, который используется повсеместно, проблема же часто встречающаяся.
Цитата Сообщение от gore-lykovoe Посмотреть сообщение
Нашел много способов, но все они страшные до безобразия.
То чего вам хочется, не увидите.
Yandex
Объявления
05.09.2013, 00:26     Какой самый универсальный способ считать UTF-8 текст на кириллице из файла?
Ответ Создать тему
Опции темы

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