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

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

Войти
Регистрация
Восстановить пароль
 
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
#1

Не получается преобразование - C++

02.03.2014, 17:50. Просмотров 283. Ответов 12
Метки нет (Все метки)

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
std::wstring                                Utf8ToWString  (std::string   &s                )
{
 size_t        BufferSize;
 wchar_t      *Buffer;
 std::wstring  Result=L"";
 if (!s.empty())
 {
  BufferSize=MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, s.c_str(), s.capacity(), NULL, 0);
  Buffer=new wchar_t [BufferSize+1];
  if (Buffer!=NULL)
  {
   MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, s.c_str(), s.capacity(), Buffer, BufferSize);
   Buffer[BufferSize]=L'\0';
   Result=Buffer;
  }
 }
 return Result;
s хранит строку в UTF8, капасити правильная, а BufferSize нулевая.
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
02.03.2014, 17:50     Не получается преобразование
Посмотрите здесь:

C++ Преобразование числа
преобразование массива C++
Преобразование классов C++
C++ Преобразование в Unicode
C++ преобразование
C++ Преобразование С++
C++ Преобразование +'0'
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Somebody
2777 / 1591 / 142
Регистрация: 03.12.2007
Сообщений: 4,170
Завершенные тесты: 1
02.03.2014, 18:10     Не получается преобразование #2
Buffer не может быть равен NULL - при ошибке будет исключение. Кто delete будет и почему бы сразу в Result не писать? Длина строки - size или length, а не capacity. Возвращаемый MultiByteToWideChar размер уже учитывает нулевой символ.
И в любом случае при ошибках смотри, что вернёт GetLastError().
DrOffset
6851 / 4062 / 927
Регистрация: 30.01.2014
Сообщений: 6,859
02.03.2014, 18:13     Не получается преобразование #3
Сообщение было отмечено автором темы, экспертом или модератором как ответ
tarasproger, почти все правильно, кроме использования capacity, проверки на NULL результата new и отсутствия освобождения памяти.
Вот я подправил, все работает:
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
#include <iostream>
#include <string>
#include <windows.h>
 
std::wstring Utf8ToWString(std::string const & s)
{
    std::wstring result;
    if(!s.empty())
    {
        int length = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), s.size(), 0, 0);
        wchar_t * out = new wchar_t[length];
        MultiByteToWideChar(CP_UTF8, 0, s.c_str(), s.size(), out, length);
        result.assign(out, length);
        delete [] out;
    }
    return result;
}
 
int main()
{
    setlocale(LC_ALL, "");
 
    std::string s = "привет мир!";
 
    std::wcout << L"[" << Utf8ToWString(s) << L"]\n";
}
Ну и проверку length на ноль неплохо бы еще добавить.
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
02.03.2014, 18:15  [ТС]     Не получается преобразование #4
Цитата Сообщение от Somebody Посмотреть сообщение
Buffer не может быть равен NULL - при ошибке будет исключение.
Когда он NULL, я ещё не знаю, какого размера мне нужен будет буфер, соответственно не могу его выделить и он не может не быть NULL, второй же раз он не равен NULL.
Цитата Сообщение от Somebody Посмотреть сообщение
и почему бы сразу в Result не писать?
Потому что Result имеет тип std::wstring, а писать надо в wcahr_t*.
DrOffset
6851 / 4062 / 927
Регистрация: 30.01.2014
Сообщений: 6,859
02.03.2014, 18:19     Не получается преобразование #5
tarasproger, Он говорит о том, что new НЕ возвращает ноль, если память выделить не удалось. new бросает исключение std::bad_alloc.
Somebody
2777 / 1591 / 142
Регистрация: 03.12.2007
Сообщений: 4,170
Завершенные тесты: 1
02.03.2014, 18:24     Не получается преобразование #6
Цитата Сообщение от tarasproger Посмотреть сообщение
Потому что Result имеет тип std::wstring, а писать надо в wcahr_t*.
C++
1
2
result.reserve(length);
MultiByteToWideChar(..., &result[0], ...);
?
DrOffset
6851 / 4062 / 927
Регистрация: 30.01.2014
Сообщений: 6,859
02.03.2014, 18:25     Не получается преобразование #7
Somebody, такое легально только в С++11.
castaway
Эксперт С++
4876 / 3015 / 370
Регистрация: 10.11.2010
Сообщений: 11,075
Записей в блоге: 10
Завершенные тесты: 1
02.03.2014, 18:33     Не получается преобразование #8
Такое легально даже в Си.
DrOffset
6851 / 4062 / 927
Регистрация: 30.01.2014
Сообщений: 6,859
02.03.2014, 18:36     Не получается преобразование #9
castaway, в С++03 не было ни гарантии на какую-то конкретную внутреннюю реализацию, ни на то, что строка будет храниться непрерывно. Например в случае COW-строки мы таким образом можем запросто нарушить инвариант. В С++11 появились гарантии и требования к реализации, которые позволяют обезопасить данный способ от побочных эффектов.
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
02.03.2014, 18:37  [ТС]     Не получается преобразование #10
Конкретное внутреннее представление строки стандартом не гарантировано, так что это не допускается даже в c++. А вот оператор присваивания нуль-терминальной строки wstring-строке гарантировано перегружен с учётом всех особенностей внутреннего представления.
castaway
Эксперт С++
4876 / 3015 / 370
Регистрация: 10.11.2010
Сообщений: 11,075
Записей в блоге: 10
Завершенные тесты: 1
02.03.2014, 18:42     Не получается преобразование #11
Я отвечал на 7-й пост. Наверное мы друг друга не поняли.
Somebody
2777 / 1591 / 142
Регистрация: 03.12.2007
Сообщений: 4,170
Завершенные тесты: 1
02.03.2014, 18:42     Не получается преобразование #12
Да, точно, только в C++11.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
02.03.2014, 18:44     Не получается преобразование
Еще ссылки по теме:

C++ Преобразование
Преобразование C++
C++ String в char. Не получается преобразование
Преобразование температуры C++
C++ Преобразование типов в С++

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

Или воспользуйтесь поиском по форуму:
DrOffset
6851 / 4062 / 927
Регистрация: 30.01.2014
Сообщений: 6,859
02.03.2014, 18:44     Не получается преобразование #13
Вот вам из стандарта С++11 (21.4.1/5):
The char-like objects in a basic_string object shall be stored contiguously. That is, for any basic_string
object s, the identity &*(s.begin() + n) == &*s.begin() + n shall hold for all values of n such that 0 <= n < s.size().
Yandex
Объявления
02.03.2014, 18:44     Не получается преобразование
Ответ Создать тему
Опции темы

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