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

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 57, средняя оценка - 4.98
GetHelp
-7 / 61 / 6
Регистрация: 27.02.2013
Сообщений: 1,112
#1

Std::string and std::wstring convert - C++

02.10.2014, 11:47. Просмотров 9472. Ответов 20
Метки нет (Все метки)

случайно наткнулся на такую вот конвертацию std::string в std::wstring

C++
1
2
3
std::string text("text");
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
std::wstring wtext = converter.from_bytes(text);
а как можно сделать обратное преобразование? т.е. std::wstring в std::string? чтоб только вот как то по аналогии в пару строк можно было...

Добавлено через 2 минуты
а все отбой там же еще есть метод to_bytes тупанул

Добавлено через 15 часов 49 минут
погодите ка, написал вот так:
C++
1
2
3
4
5
6
7
8
9
10
11
std::wstring to_wstring(const std::string& text)
{
    std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
    return converter.from_bytes(text);
}
 
std::string to_string(const std::wstring& text)
{
    std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
    return converter.to_bytes(text);
}
но при попытке сконвертить русские символы падает с ошибкой "Необработанное исключение по адресу..."
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
02.10.2014, 11:47
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Std::string and std::wstring convert (C++):

ошибка error: cannot convert 'std::string {aka std::basic_string<char>}' to 'std::string* {aka std::basic_stri - C++
на вод поступают 2 строки типа string. определить количество вхождений строки 2 в строку 1 ошибка error: cannot convert 'std::string {aka...

Как правильно перевести std::wstring в std::string ? - C++
Собственно как? :)

Как привести std::wstring к std::string? - C++
Как привести std::wstring к std::string?

std::string -> std::wstring - C++
Как перевести данный код в код с использованием wstring ( посути использовать std::vector&lt;std::wstring&gt; refs; ) #include &lt;vector&gt; ...

ошибка в программе (cannot convert 'std::string {aka std::basic_string<char>}' to 'const char*') - C++
int main() { string fileName, currWord, currMax = &quot;&quot;; cin&gt;&gt;fileName; freopen(fileName, &quot;r&quot;, stdin); while...

На основе исходного std::vector<std::string> содержащего числа, создать std::vector<int> с этими же числами - C++
подскажите есть вот такая задача. Есть список . Создать второй список, в котором будут все эти же числа, но не в виде строк, а в виде...

20
MrGluck
Модератор
Эксперт CЭксперт С++
7510 / 4642 / 700
Регистрация: 29.11.2010
Сообщений: 12,675
02.10.2014, 16:31 #16
Цитата Сообщение от Voivoid Посмотреть сообщение
речь-то вроде о std::wstring_convert? При чем тут std::to_wstring ?
Я как бы про другое писал.
Цитата Сообщение от MrGluck Посмотреть сообщение
to_wstring
Её нельзя использовать для преобразования string в wstring.
Цитата Сообщение от Voivoid Посмотреть сообщение
Её нельзя использовать для преобразования string в wstring.
Воу-воу-воу, я конечно не знаток, но твой код на первый взгляд не сильно отличается от того, как реализован std::wstring_convert. Что там по-твоему не так-то?
Решение зависит от того, из какой кодировки в какую нужно переводить. Если из ANSI в UTF8, то std::wstring_convert не пойдёт т.к.
std::wstring_convert assumes ownership of the conversion facet, and cannot use a facet managed by a locale
Я же предложил вариант перевода из ANSI (string) в UTF8 (wstring)
0
kzru_hunter
1102 / 771 / 58
Регистрация: 01.02.2011
Сообщений: 1,779
Записей в блоге: 1
17.11.2015, 23:48 #17
Да, в чистом visual c++ проблема с конвертированием (std::string(ANSI)<->std:wstring(ANSI)). В билдере просто тупо пишешь WideString wStr = str;

Вот мои заготовки для visual c++:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
std::wstring to_wstring(char *str)
{
    int max_len = strlen(str)+1;
    std::wstring wstr; wstr.resize(max_len);    
    MultiByteToWideChar(CP_ACP, 0, str, -1, (LPWSTR)wstr.c_str(), max_len);
    return wstr;
}
 
std::string to_string(wchar_t *wstr)
{
    int max_len = lstrlen(wstr);
    std::string str; str.resize(max_len);
    WideCharToMultiByte(CP_ACP, 0, wstr, -1, (LPSTR)str.c_str(), max_len, NULL, NULL);
    return str;
}
Единственно, нельзя использовать таким образом:
C++
1
2
char *str = "некоторая строка";
wchar_t *wstr = (wchar_t*)to_wstring(str).c_str(); // тут создаётся временный объект wstring и возвращается указатель на его данные, после этой строки объект уничтожится вместе с данными
Добавлено через 31 минуту
Хотя наверно лучше использовать auto_ptr, чтобы не попасться в ситуацию, описанную выше.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
std::auto_ptr<WCHAR> to_wchar_str(char *str)
{
    int max_len = strlen(str)+1;
    WCHAR *wstr = new WCHAR[max_len];
    MultiByteToWideChar(CP_ACP, 0, str, -1, wstr, max_len);
    return std::auto_ptr<WCHAR>(wstr);
}
 
std::auto_ptr<char> to_char_str(wchar_t *wstr)
{
    int max_len = lstrlen(wstr)+1;
    char *str = new char[max_len];  
    WideCharToMultiByte(CP_ACP, 0, wstr, -1, str, max_len, NULL, NULL);
    return std::auto_ptr<char>(str);
}
И использовать следующим образом:
char *path = "некоторая строка";
auto wpath = to_wchar_str(path); // auto будет работать, если есть поддержка C++11
0
DrOffset
7387 / 4464 / 1013
Регистрация: 30.01.2014
Сообщений: 7,317
18.11.2015, 08:27 #18
Цитата Сообщение от kzru_hunter Посмотреть сообщение
лучше использовать auto_ptr,
auto_ptr нельзя использовать для массивов.
0
kzru_hunter
1102 / 771 / 58
Регистрация: 01.02.2011
Сообщений: 1,779
Записей в блоге: 1
18.11.2015, 11:45 #19
С auto_ptr тоже гемор. Короче остановился на таком варианте.
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
namespace convert
{
    // конвертирует std::string -> [ANSI] -> std::wstring
    int StrToWStr(std::wstring &dest, const std::string &source)
    {
        int source_len = source.length();
 
        dest.resize(source_len + 1);
        int dest_len = MultiByteToWideChar(CP_ACP, 0, source.c_str(), -1, (WCHAR*)dest.c_str(), source_len + 1);
 
        return dest_len;
    }
 
    // конвертирует std::wstring -> [ANSI] -> std::string
    int WStrToStr(std::string &dest, const std::wstring &source)
    {
        int source_len = source.length() + 1;
 
        dest.resize(source_len * 2 + 1);
        int dest_len = WideCharToMultiByte(CP_ACP, 0, source.c_str(), -1, (LPSTR)dest.c_str(), source_len * 2 + 1, NULL, NULL);
        dest.resize(dest_len); dest.shrink_to_fit(); // укорачивание памяти под dest
 
        return dest_len;
    }
 
    // конвертирует std::string -> [CodePage] -> std::string
    int StrTo(std::string& dest, const std::string& source, UINT ResultCodePage = CP_ACP, DWORD dwFlags = 0) // параметры см. в WideCharToMultiByte
    {
        int source_len = source.length();
 
        WCHAR *wstr = new WCHAR[source_len + 1];
        MultiByteToWideChar(CP_ACP, 0, source.c_str(), -1, wstr, source_len + 1);
 
        dest.resize(source_len * 2 + 1);
        int dest_len = WideCharToMultiByte(ResultCodePage, dwFlags, wstr, -1, (LPSTR)dest.c_str(), source_len * 2 + 1, NULL, NULL);
        dest.resize(dest_len); dest.shrink_to_fit(); // укорачивание памяти под dest
 
        delete[] wstr;
 
        return dest_len;
    }
 
    // конвертирует std::wstring -> [CodePage] -> std::string
    int WStrTo(std::string& dest, const std::wstring& source, UINT ResultCodePage = CP_ACP, DWORD dwFlags = 0) // параметры см. в WideCharToMultiByte
    {
        int source_len = source.length();
 
        dest.resize(source_len * 2 + 1);
        int dest_len = WideCharToMultiByte(ResultCodePage, dwFlags, source.c_str(), -1, (LPSTR)dest.c_str(), source_len * 2 + 1, NULL, NULL);
        dest.resize(dest_len); dest.shrink_to_fit(); // укорачивание памяти под dest
 
        return dest_len;
    }
}
0
Tulosba
:)
Эксперт С++
4397 / 3233 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
18.11.2015, 17:45 #20
Цитата Сообщение от kzru_hunter Посмотреть сообщение
С auto_ptr тоже гемор.
К тому же он deprecated, тем более, что раз уж используется shrink_to_fit, то это C++11.
В StrTo можем получить утечки, если resize кинет исключение.
Поэтому, я бы как минимум, предложил заменить
C++
1
WCHAR *wstr = new WCHAR[source_len + 1];
на
C++
1
std::vector<WCHAR> wstr(source_len + 1);
P.S. И как мне кажется, можно вообще обойтись стандартными (c++11) средствами, без виндозных MultiByteToWideChar. Поправьте, если ошибаюсь.

Лучше даже не std::vector, т.к. всякие векторные операции не нужны, а
C++
1
std::unique_ptr<WCHAR[]> wstr(new WCHAR[source_len + 1]);
Для с++14:
C++
1
auto wstr = std::make_unique<WCHAR[]>(source_len + 1);
0
kzru_hunter
1102 / 771 / 58
Регистрация: 01.02.2011
Сообщений: 1,779
Записей в блоге: 1
18.11.2015, 20:17 #21
Tulosba Ага, спс за поправку насчет утечки. Переделал снова немного К сожалению, unique-ptr не использовал (с ним быстрее выполняется где-то на 5%), т.к. решил укоротить функцию StrStr за счет использования двух других.
Цитата Сообщение от Tulosba Посмотреть сообщение
P.S. И как мне кажется, можно вообще обойтись стандартными (c++11) средствами, без виндозных MultiByteToWideChar. Поправьте, если ошибаюсь.
По-моему, эти функции по скорости преобразования самые быстрые, чем использование каких-либо других средств.

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
namespace convert
{
    // конвертирует std::string -> [ResultCodePage] -> std::wstring
    int StrToWStr(std::wstring &dest, const std::string &source, UINT ResultCodePage = CP_ACP, DWORD dwFlags = 0) // параметры см. в MultiByteToWideChar
    {
        dest.resize(source.length() +1);                
        return MultiByteToWideChar(ResultCodePage, dwFlags, source.c_str(), source.length(), (WCHAR*)dest.c_str(), source.length() + 1);
    }
 
    // конвертирует std::wstring -> [ResultCodePage] -> std::string
    int WStrToStr(std::string &dest, const std::wstring &source, UINT ResultCodePage = CP_ACP, DWORD dwFlags = 0) // параметры см. в WideCharToMultiByte
    {
        int dest_len = WideCharToMultiByte(ResultCodePage, dwFlags, source.c_str(), source.length(), (LPSTR)dest.c_str(), 0, NULL, NULL);
        dest.resize(dest_len);      
        WideCharToMultiByte(ResultCodePage, dwFlags, source.c_str(), source.length(), (LPSTR)dest.c_str(), dest_len, NULL, NULL);
 
        return dest_len;
    }       
 
    // конвертирует std::string -> [ResultCodePage] -> std::string
    int StrToStr(std::string& dest, const std::string& source, UINT ResultCodePage = CP_ACP, DWORD dwFlags = 0) // параметры см. в WideCharToMultiByte
    {
        std::wstring wstr; StrToWStr(wstr, source);
        return WStrToStr(dest, wstr, ResultCodePage, dwFlags);      
    }
}
0
18.11.2015, 20:17
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
18.11.2015, 20:17
Привет! Вот еще темы с ответами:

Ошибка Cannot convert std::string to void* - C++
Не могу сконвертировать строку в void*: std::string str; (void*)str; Вернее invalid cast from type std::string to type void* ...

cannot convert parameter 1 from 'int' to 'std::string &' - C++
string kolvo(string &amp;S, int &amp;k) { unsigned int i; for(i=1; i&lt;S.length(); i++) if(S=='B' &amp;&amp; S==' ') k=k+1; } ...

запрошено преобразование от ‘const std::string*’ к нескалярному типу ‘std::string’ - C++
private: std::string firstName; }; std::string ClientData::getFirstName() const{ return firstName; } Дает в итоге...

Реализация класса MyString. Стандартная библиотека, std::string, std::vector - C++
как добавить реализацию конкатенации строк через перегрузку оператора &quot;+=&quot; в классе MyString и почему ошибка выдается???#include...


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

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

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