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

C++

Войти
Регистрация
Восстановить пароль
 
hoggy
6672 / 2856 / 491
Регистрация: 15.11.2014
Сообщений: 6,371
Завершенные тесты: 1
#1

[mingw] не видит <codecvt> - C++

31.01.2016, 21:50. Просмотров 716. Ответов 10
Метки нет (Все метки)

всем привет.

есть библиотека, которая изначально разрабатывалась в msvc2013.
к библиотеке есть требование - кросс-платформа,
и отсутствие внешних зависимостей.

то есть, нельзя подтягивать буст,
и подобные тяжеловесные вещи.

казалось бы - никаких левых зависимостей,
стандартная библиотека во все поля.
однако, при попытке портануться на mingw (942, что идет в коробке с qt5.5.1),
вылезла проблема:

для работы понадобилось выполнять преобразования кодировок текста.
наиболее актуальным является конвертация utf8 <----> unicode

что в коде выглядит,
как преобразование std::string <----> std::wstring

что бы было понятнее,
проиллюстрирую этот момент:

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
// cmdconv.h
 
#pragma once
 
namespace cmd{
 
// =======================================================================
// =======================================================================
 
    namespace multibyte {
        std::string  convert(const wchar_t* s);
        std::wstring convert(const char*    s);
        std::string  convert(const std::wstring& s);
        std::wstring convert(const std::string&  s);
    }// namespace multibyte 
 
    namespace utf8 {
        std::string  convert(const std::wstring& s);
        std::wstring convert(const std::string&  s);
    }// namespace utf8 
 
    namespace stdlocal {
 
        std::string convert(
            const wchar_t* s,
            const size_t len,
            const std::locale& loc = std::locale(),
            const char default_char = '?'
        );
        std::string convert(
            const wchar_t* s, 
            const std::locale& loc = std::locale(""), 
            const char default_char = '?'
        );
        std::string convert(
            const std::wstring& s, 
            const std::locale& loc = std::locale(""), 
            const char default_char = '?'
        );
        std::wstring convert(
            const char* s,
            const std::locale& loc = std::locale("")
        );
        std::wstring convert(
            const std::string& s, 
            const std::locale& loc = std::locale("") 
        );
        std::wstring convert(
            const char* s, 
            const size_t len, 
            const std::locale& loc = std::locale()
        );
 
    } //namespace stdlocal 
 
// =======================================================================
// =======================================================================
 
}//namespace cmd
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
//cmdconv.cpp
 
#include "precompiled.h"
 
#include <cmd/cmdconv.h>
 
namespace cmd{
 
// =======================================================================
// =======================================================================
 
    namespace multibyte {
 
        std::string convert(const std::wstring& s)
            { return convert( s.c_str() ); }
        std::wstring convert(const std::string& s)
            { return convert(s.c_str()); }
 
        std::string convert(const wchar_t* s)
        { 
            const size_t len = wcslen(s);
            std::string result(len,'\0');
 
            #ifdef _MSC_VER
                size_t count = 0;
                const auto size_ = result.size();
                wcstombs_s(&count, &result[0], size_, s, size_ );
            #else
                std::mbstate_t state = std::mbstate_t();
                std::wcsrtombs( &result[0], &s, result.size(), &state);
            #endif
 
            return result;
        }
 
        std::wstring convert(const char* s)
        { 
            std::mbstate_t state  = std::mbstate_t(); 
        
            size_t len;
            wchar_t wc[4] = {};
            std::wstring result;
            const char* end = s + std::strlen(s);
        
            //TODO: remove warning:
            //conversion to 'size_t {aka unsigned int}' from 'int' 
            //may change the sign of the result [-Wsign-conversion] 
            while ((len = std::mbrtowc(wc, s, end - s, &state)) > 0 )
            {
                result += wc; s += len;
                for (auto& ch: wc)  ch = L'\0';
            }
            return result;
        }
    }//namespace multibyte
 
 
    namespace utf8 {
        
    #if defined(__MINGW__) || defined(__MINGW32__)
    
    // no support
    
    #else
 
        std::string convert(const std::wstring& s)
        { 
            typedef std::codecvt_utf8<wchar_t>
                convert_typeX;
            std::wstring_convert<convert_typeX,wchar_t>
                converterX;
            return converterX.to_bytes(s);
        }
        std::wstring convert(const std::string&  s)
        { 
            typedef std::codecvt_utf8<wchar_t>
                convert_typeX;
            std::wstring_convert<convert_typeX,wchar_t>
                converterX;
            return converterX.from_bytes(s);
        }
    #endif
            
    }//namespace utf8 
 
    namespace stdlocal {
 
        std::wstring convert(const char* first, const size_t len, const std::locale& loc)
        {
            if(len == 0)
                return std::wstring();
 
            const std::ctype<wchar_t>& facet =
                std::use_facet< std::ctype<wchar_t> >(loc);
 
            const char* last = first + len;
 
            std::wstring result(len, L'\0');
 
            facet.widen(first, last, &result[0]);
            return result;
        }
 
        std::string convert(
            const wchar_t* first,
            const size_t len,
            const std::locale& loc,
            const char default_char
        )
        {
            if(len == 0)
                return std::string();
 
            const std::ctype<wchar_t>& facet =
                std::use_facet<std::ctype<wchar_t> >(loc);
 
            const wchar_t* last  = first + len;
 
            std::string result( len, default_char );
            facet.narrow( first, last, default_char, &result[0] );
            return result;
        }
 
        std::string  convert( const wchar_t* s, const std::locale& loc, const char default_char )
            { return convert(s, std::wcslen(s), loc, default_char); }
        std::string  convert(const std::wstring& s, const std::locale& loc, const char default_char)
            { return convert(s.c_str(), s.length(), loc, default_char);  }
        std::wstring convert( const char* s, const std::locale& loc)
            { return convert(s, std::strlen(s), loc); }
        std::wstring convert( const std::string& s, const std::locale& loc)
            { return convert(s.c_str(), s.length(), loc); }
 
    }//namespace stdlocal
 
// =======================================================================
// =======================================================================
 
}//namespace cmd


C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//precompiled.h
 
#pragma once
 
#pragma message("PRECOMPILE CMDCONV HEADER ...")
 
#include <cassert>
 
#if defined(__MINGW__) || defined(__MINGW32__)
    #include <stdexcept>
    #include <cstring>
    #include <locale>
#else
 
    //TODO: No such file or directory
    // WTF ????
    #include <codecvt>
#endif
 
#include <string>
оказывается, mingw не умеет юникод!
он вообще не знает ни о каких
C++
1
#include <codecvt>
гугл не утешителен.
в основном советуют смотреть в сторону boost.


но я себе этого позволить не могу.

какие могут быть обходные пути?
или как можно заставить работать мои конвертеры?
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
31.01.2016, 21:50
Здравствуйте! Я подобрал для вас темы с ответами на вопрос [mingw] не видит <codecvt> (C++):

Mingw и windows.h - C++
Возникла ошибка в том что mingw определяет мою систему без unicode, а windows.h как unicode, и например при обращение к ф-ции...

mingw и лицензия - C++
Интересует следующий вопрос. Можно ли создавать ПО под лицензией, отличной от GPL (или с закрытым\частично закрытым кодом)? ПО собрано...

mingw и lib - C++
Как в mingw в коде подключить файл lib, #pragma comment(lib, &quot;Gdi32.lib&quot;) не помогает. А то пытаюсь использовать SetTextColor и подобные...

Gcc без MinGW - C++
Интересует вопрос, можно ли рабочий код (который без ошибок компилируется в Visual Studio) компилировать с помощью командной строки Windows...

libcUrl с OpenSSL на MinGW - C++
Помогите! Никак не могу разобраться с libcUrl с OpenSSL, просто libcUrl компилю без проблем, и использую, но нужнен https. ...

MSVS или MINGW - C++
Привет всем. У меня скоро заканчивается пробная версия visual studio и я думаю установить mingw(операционная система Windows). Как mingw?...

10
Croessmah
Эксперт CЭксперт С++
13513 / 7671 / 866
Регистрация: 27.09.2012
Сообщений: 18,884
Записей в блоге: 3
Завершенные тесты: 1
31.01.2016, 22:08 #2
Цитата Сообщение от hoggy Посмотреть сообщение
оказывается, mingw не умеет юникод!
Насколько я помню,
mingw даже нестандартные локали не умеет в std::locale.
Плюется исключениями
1
castaway
Эксперт С++
4885 / 3020 / 370
Регистрация: 10.11.2010
Сообщений: 11,078
Записей в блоге: 10
Завершенные тесты: 1
01.02.2016, 19:34 #3
Я несколько раз пытался проделать подобное в MinGW 5.2.0 но ни разу не получал нужного результата. Насколько я помню, опыты почти всегда оканчивались исключением.
На тот момент я видел только один выход - преобразование вручную.
1
AlexVRud
452 / 163 / 41
Регистрация: 04.07.2014
Сообщений: 465
02.02.2016, 15:17 #4
Цитата Сообщение от hoggy Посмотреть сообщение
какие могут быть обходные пути?
или как можно заставить работать мои конвертеры?
Для платформ без поддержки codecvt использовать реализации на базе boost/icu
0
hoggy
6672 / 2856 / 491
Регистрация: 15.11.2014
Сообщений: 6,371
Завершенные тесты: 1
02.02.2016, 18:20  [ТС] #5
111111111

Цитата Сообщение от AlexVRud Посмотреть сообщение
Для платформ без поддержки codecvt использовать реализации на базе boost/icu
Цитата Сообщение от hoggy Посмотреть сообщение
и отсутствие внешних зависимостей.
то есть, нельзя подтягивать буст,
и подобные тяжеловесные вещи.
0
AlexVRud
452 / 163 / 41
Регистрация: 04.07.2014
Сообщений: 465
02.02.2016, 20:51 #6
Цитата Сообщение от hoggy Посмотреть сообщение
кросс-платформа,
и
wstring, codecvt, locale
уже не совместимы. Например в CentOS 7 gcc 4.8, при этом ещё никуда не ушел CentOS 6.

Даже Qt не стал заморачиваться и воспользовался ICU. Одно дело, когда отказываются от непредсказуемого boost. Но когда вместо icu/zlib/openssl/... начинают лепить свои велосипеды,....
0
castaway
Эксперт С++
4885 / 3020 / 370
Регистрация: 10.11.2010
Сообщений: 11,078
Записей в блоге: 10
Завершенные тесты: 1
02.02.2016, 21:00 #7
Цитата Сообщение от AlexVRud Посмотреть сообщение
уже не совместимы.
o_O
0
AlexVRud
452 / 163 / 41
Регистрация: 04.07.2014
Сообщений: 465
02.02.2016, 21:36 #8
Цитата Сообщение от castaway Посмотреть сообщение
o_O
  1. wchar_t может иметь размер в 8,16,32 бита на разных платформах
  2. #include <codecvt> - много ли где отработает?
  3. locale - Russian_Russia/ru_RU/??? не говоря о различных реализациях, и их отсутствия напрочь на большинстве платформ.
0
castaway
Эксперт С++
4885 / 3020 / 370
Регистрация: 10.11.2010
Сообщений: 11,078
Записей в блоге: 10
Завершенные тесты: 1
02.02.2016, 21:46 #9
1. ссылку можно?
2. не понял что вы имели в виду
3. не понял что вы имели в виду

Все нюансы должна предусмотреть стандартная библиотека C++. Иначе она не была бы стандартной.
0
Croessmah
Эксперт CЭксперт С++
13513 / 7671 / 866
Регистрация: 27.09.2012
Сообщений: 18,884
Записей в блоге: 3
Завершенные тесты: 1
02.02.2016, 22:08 #10
Цитата Сообщение от castaway Посмотреть сообщение
1. ссылку можно?
На винде 2 байта, на лине 4 байта.
Цитата Сообщение от castaway Посмотреть сообщение
3. не понял что вы имели в виду
названия локалей везде свои.
1
Dmitriy_M
1357 / 1240 / 114
Регистрация: 20.03.2009
Сообщений: 4,441
Записей в блоге: 11
03.02.2016, 11:03 #11
Цитата Сообщение от AlexVRud Посмотреть сообщение
Даже Qt не стал заморачиваться и воспользовался ICU
Вот в Qt они заморочились как и в Boost.Поддерживается не только ICU, но libiconv
0
03.02.2016, 11:03
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
03.02.2016, 11:03
Привет! Вот еще темы с ответами:

Как интегрировать Notepad++ с MinGW компилятором? - C++
Уважаемые форумчане, подскажите как можно грамотно интегрировать Notepad++ (или аналогичный редактор с подcветкой разных синтаксисов) с...

Баг в MinGW при использовании fread - C++
Ну собственно вот простой тестовый код который выполняется некорректно: #include &lt;cstdio&gt; using namespace std; const int N =...

Не удается запустить С++ приложение в среде NetBeans 7.0.1 (MinGW) - C++
Здравствуйте, Не получается запустить приложение в среде NetBeans версии 7.0.1. Настроил по идее все как полагается: Установил MinGW,...

Сборки MinGW(GCC-win32/win64) от niXman - C++
с этого момента, буду производить тестовые/пререлизные/релизные сборки mingw. файлы с пометкой snapshot и prerelease - не стабильные...


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

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

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