2015-01-14 43 views
0

我做了一個簡單的C++服務器程序,只要我用telnet這樣簡單的工具就可以工作,但是當我使用例如.Net (C#)將連接到它併發送一些字符串,文本有些損壞。我在C#端嘗試了多種編碼,只是結果是它以不同的方式損壞了。如何通過linux套接字將UTF-8文本轉換爲std :: string

我相信這主要的問題是在這個函數,是爲了從套接字讀取一行文字:

std::string Client::ReadLine() 
{ 
    std::string line; 
    while (true) 
    { 
     char buffer[10]; 
     read(this->Socket, buffer, 9); 
     int i = 0; 
     while (i < 10) 
     { 
      if (buffer[i] == '\r') 
      { 
       i++; 
       continue; 
      } 
      if (buffer[i] == '\0') 
      { 
       // end of string reached 
       break; 
      } 
      if (buffer[i] == '\n') 
      { 
       return line; 
      } 
      line += buffer[i]; 
      i++; 
     } 
    } 
    return line; 
} 

這是程序的簡單輸出到終端,當我把它串「恩。 wikipedia.org」使用telnet我看到:

Subscribed to en.wikipedia.org 

當我使用C#,使用此代碼

streamWriter = new StreamWriter(networkStream, Encoding.UTF8); 
打開一個流作家

我看到:

Subscribed to en.wiki,pedia.org, 

當我使用它,而UTF-8(以便使用默認的.NET編碼,IDK它是什麼)

streamWriter = new StreamWriter(networkStream); 

我看到:

Subscribed to en.wiki�pedia.org� 

但是,在這兩種情況下都是錯誤的。使用標準的C++和Linux庫,實現這個最簡單的方法是什麼? (沒有提升等 - 我可以使用一些框架,如Qt,boost等,但我想明白這一點)。完整代碼@http://github.com/huggle/XMLRCS

+0

如果你使用std :: wstring會發生什麼? – Neska

+4

我認爲你正在讀9個字符,但從緩衝區複製10個字符。 – Galik

+0

你可能會發現這個鏈接有趣:http://en.cppreference.com/w/cpp/locale/codecvt –

回答

2

UTF-8字符串只是一系列單字節,基本上只有std::string應該處理。你有兩個其他的問題:

第一個是你沒有真正檢查許多字符是否被實際讀取,你總是循環十個字符。由於您不會循環讀取的實際字符數(並且不檢查錯誤或連接結束),因此您可能讀取的數據超出了read所寫的數據量,並且您有undefined behavior

第二個問題是一種涉及到第一,那就是你有十個字符緩衝區,你看最多九個字符到緩衝區,並在隨後遍歷所有十個​​字符緩衝。問題在於,由於您只能讀取9個字符,因此第10個字符將始終未初始化。由於緩衝區中的第十個條目始終未初始化,因此其值將不確定,並且讀取它將再次導致未定義的行爲。

相關問題