2015-04-05 75 views
-2

我試圖從stdin中取出wchar_t字符串,然後通過函數將其從Unicode轉換爲ASCII。Unicode到ASCII轉換後聲明std :: string給出分割錯誤

該函數在某種程度上不允許我在程序中進一步使用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。 Unicode更復雜。 – deviantfan 2015-04-05 18:24:35

+0

除此之外,您的測試輸入將有所幫助。這可能是原因。 – deviantfan 2015-04-05 18:25:45

+0

好的,這可能是錯誤的,但我試圖在函數中將** wchar_t **轉換爲** char **,然後我無法在我的程序中使用std :: string。這很奇怪.. – 2015-04-05 18:27:17

回答

-1
  • 你永遠不會寫入無效的指針之前c分配內存。
  • cin >>對固定大小的數組不安全。你可能會考慮std::wstring
  • 如果要將16位字符轉換爲8位字符,請在8位字符串中使用UTF-8編碼,而不是ASCII。如果您必須使用ASCII,則必須錯誤判斷任何字符是否超出範圍,否則請將其替換爲佔位符字符。但是,這會讓你沒有國際支持。你應該能夠很容易地找到關於用C++將UTF-16轉換爲UTF-8的信息。
+0

三件事:雖然將UTF16轉換爲UTF8比真正的OPs更容易,但他甚至說他的源數據是UTF16?誰說他可以使用UTF8來處理他需要的轉換數據?而且......'將Unicode轉換爲UTF-8'請不要。 UTF8 *是* Unicode,不是全部。 – deviantfan 2015-04-05 18:57:23

+0

我提出了三種用於以8位格式存儲轉換數據的選項。我不知道有任何其他選項。 – 2015-04-05 19:01:06

+0

儘管在答案中我沒有看到*三種不同的轉換方法,但這並不重要,因爲它不回答這個問題。 (並且,第四件事:OP不使用cin) – deviantfan 2015-04-05 19:03:30

2

您沒有爲c分配任何內存,所以您正在將字符數據寫入隨機內存並損壞您的程序。

您應該停止使用字符數組和原始指針,並開始使用std::stringstd::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字符(0×00 - 0x7F的)。正確處理Unicode比這複雜得多。但是這會回答你的一個直接問題,那就是你爲什麼在調用你的函數之後不能使用std::string--因爲你正在破壞內存。