C++中如何将服务器返回的字节字符串转换为普通字符串
解决字节流转字符串的问题
你现在看到的657865...其实是每个字节的十进制数值(比如65对应'A',78对应'N'),问题出在你只把单个字节的数值转换成了字符串,而没有把整个字节流解码成对应的字符序列。
问题根源
你的代码里Convert::ToString(server_reply[0])是把server_reply数组第一个元素的字节值(比如0x41,也就是十进制65)直接转成了字符串,而不是把这个字节解码成它对应的ASCII字符。而且你只取了第一个字节,自然看不到完整的服务器响应。
正确的解决方案
因为服务器返回的是ASCII编码的字节流,我们需要把接收到的字节数组用ASCII编码解码成托管字符串。在C++/CLI中,有两种简单的实现方式:
方法1:使用Marshal::PtrToStringAnsi(推荐)
这个方法可以直接把非托管的字节数组指针转换成ASCII编码的托管字符串,还能指定实际接收的字节长度,避免包含数组中未初始化的垃圾数据:
//Receive a reply from the server if((recv_size = recv(ConnectSocket , server_reply , 2000 , 0)) == SOCKET_ERROR){ MessageBox::Show("recv failed",""); //exit(1); } // 将非托管字节数组转成ASCII字符串,只取实际接收的recv_size长度 String^ serverResponse = System::Runtime::InteropServices::Marshal::PtrToStringAnsi(IntPtr(server_reply), recv_size); this->label1->Text = serverResponse;
方法2:使用Encoding::ASCII->GetString
先把非托管的字节复制到托管的Byte数组中,再用ASCII编码解码:
//Receive a reply from the server if((recv_size = recv(ConnectSocket , server_reply , 2000 , 0)) == SOCKET_ERROR){ MessageBox::Show("recv failed",""); //exit(1); } // 创建对应长度的托管字节数组 array<Byte>^ byteBuffer = gcnew array<Byte>(recv_size); for(int i = 0; i < recv_size; i++){ byteBuffer[i] = static_cast<Byte>(server_reply[i]); } // 解码成ASCII字符串 String^ serverResponse = System::Text::Encoding::ASCII->GetString(byteBuffer); this->label1->Text = serverResponse;
注意事项
- 如果服务器实际使用的是UTF-8编码,只需要把上面的
ASCII换成UTF8即可(比如Encoding::UTF8->GetString或者PtrToStringUTF8)。 - 一定要使用
recv_size作为转换的长度,不要直接用数组的总长度(2000),否则会把数组中未被服务器填充的垃圾数据也转成字符串。
内容的提问来源于stack exchange,提问作者user2386653
相关产品推荐
相关产品推荐

