2015-04-05 6 views
-2

Я пытаюсь взять строку wchar_t из stdin, а затем преобразовать ее из Unicode в ASCII через функцию.Объявление std :: string после преобразования Unicode в ASCII дает ошибку сегментации

Функция как-то не позволяет мне использовать std :: string дальше в программе.

#include <iostream> 
#include <string> 
#include <locale> 
#include <cstring> 
#include <cwchar> 
using namespace std; 
bool UnicodeToAscii(wchar_t* szUnicode, char* szAscii); 
int main() 
{ 
    wchar_t w[100]; 
    wcin>>w; 
    char* c; 
    bool x=UnicodeToAscii(w,c); 
    cout<<c<<"\n"; 
    string s="hi"; 
    return 0; 
} 
bool UnicodeToAscii(wchar_t* szUnicode, char* szAscii) 
{ 
    int len, i; 
    if((szUnicode == NULL) || (szAscii == NULL)) 
     return false; 
    len = wcslen(szUnicode); 
    for(i=0;i<len+1;i++) 
     *szAscii++ = static_cast<char>(*szUnicode++); 
    return true; 
} 
+0

Вы ** не ** конвертируете любую кодировку Unicode в ASCII здесь. Юникод гораздо сложнее. – deviantfan

+0

Кроме этого, ваш тестовый ввод поможет. Это может быть причиной. – deviantfan

+0

Хорошо, это может быть неправильно, но я попытался приписать ** wchar_t ** в ** char ** в функции, а затем я не могу использовать std :: string в своей программе. Это довольно странно. –

ответ

-1
  • Вы никогда не выделить память для c перед записью на неверный указатель.
  • Это небезопасно для cin >> в массив фиксированного размера. Вы можете рассмотреть std::wstring.
  • Если вы хотите конвертировать 16-битные символы в 8-битные символы, используйте кодировку UTF-8 в 8-битной строке, а не ASCII. Если вы должны использовать ASCII, вам придется выходить из системы, если какой-либо символ выходит за пределы допустимого диапазона, или заменить его символом-заполнителем. Однако это оставляет вас без международной поддержки. Вы должны иметь возможность легко найти информацию об конвертации UTF-16 в UTF-8 на C++.
+0

Три вещи. Хотя верно, что преобразование UTF16 в UTF8 намного проще, чем исходный план OPs, который даже сказал, что его исходными данными является UTF16? И кто сказал, что он может использовать UTF8 для того, что ему нужно для преобразованных данных? И ... «преобразование Unicode в UTF-8», пожалуйста, нет. UTF8 * есть * Юникод, просто не все. – deviantfan

+0

Я предложил три варианта хранения преобразованных данных в 8-битном формате. Я не знаю никаких дополнительных опций. –

+0

Хотя я не вижу в вашем ответе трех разных методов преобразования, это не имеет значения, потому что он не отвечает на вопрос. (И, четвертая вещь: OP не использует cin) – deviantfan

2

Вы не выделяете какую-либо память для c, поэтому вы пишете персональные данные в случайную память и развращаете свою программу.

Вы должны прекратить использовать массивы символов и необработанные указатели и вместо этого начать использовать std::string и std::wstring. Пусть они управляют памятью для вас.

Попробуйте это:

#include <iostream> 
#include <string> 

void UnicodeToAscii(const std::wstring &szUnicode, std::string &szAscii); 

int main() 
{ 
    std::wstring w; 
    std::wcin >> w; // or std::getline(wcin, w); 

    std::string c; 
    bool x = UnicodeToAscii(w, c); 
    std::cout << c << "\n"; 

    std::string s = "hi"; 
    return 0; 
} 

void UnicodeToAscii(const std::wstring &szUnicode, std::string &szAscii) 
{ 
    szAscii.clear(len); 

    int len = szUnicode.length(); 
    char c; 

    szAscii.reserve(len); 

    for(int i = 0; i < len; ++i) 
    { 
     wchar_t w = szUnicode[i]; 

     if ((w >= 0) && (w < 127)) 
     { 
      // ASCII character 
      c = static_cast<char>(w); 
     } 
     else 
     { 
      // non-ASCII character 
      c = '?'; 

      // wchar_t is 2 bytes (UTF-16) on some systems, 
      // but is 4 bytes (UTF-32) on other systems... 
      #if sizeof(wchar_t) == 2 
      if ((w >= 0xD800) && (w <= 0xDFFF)) 
      { 
       // skip first unit of a surrogate pair, 
       // the loop will skip the second unit... 
       ++i; 
      } 
      #endif 
     } 

     szAscii.push_back(c); 
    } 

    return true; 
} 

Конечно, это очень рудиментарным, и он обрабатывает только истинные символы ASCII (0x00 - 0x7F). Правильное управление Unicode намного сложнее, чем это. Но это отвечает на ваш непосредственный вопрос о том, почему вы не можете использовать std::string после вызова вашей функции - потому что вы перепутаете память.