vs2013中做的一个聊天室程序,发送中文时出现了很多关于字符集编码的有关问题,望大神帮帮小弟我这个菜鸟
vs2013中做的一个聊天室程序,发送中文时出现了很多关于字符集编码的问题,望大神帮帮我这个初学者
我是照着孙鑫老师的视频做的一个聊天室程序,发送英文没问题,中文却出现很多问题啊
void CChatDlg::OnBnClickedBtnSend()
{
DWORD ipaddr;
((CIPAddressCtrl*)GetDlgItem(IDC_IPADDRESS3))->GetAddress(ipaddr);
SOCKADDR_IN addrSend;
addrSend.sin_addr.S_un.S_addr = htonl(ipaddr);
addrSend.sin_family = AF_INET;
addrSend.sin_port = htons(6000);
CString strsend;
string str;
const char* _s;
GetDlgItemText(IDC_EDIT_SEND, strsend);
str = CStringToString(strsend);
_s = str.c_str();
sendto(m_socket,_s,strsend.GetLength()+1,0,
(SOCKADDR*)&addrSend, sizeof(SOCKADDR));
SetDlgItemText(IDC_EDIT_SEND, TEXT(""));
// TODO: 在此添加控件通知处理程序代码
}
string CStringToString(CString cstr)
{
size_t i;
string str;
setlocale(LC_ALL, "chs");
wchar_t wch[255];
char temp[255];
wcscpy_s(wch, cstr.GetString());
wcstombs_s(&i, temp, wch, 254);
str.append(temp);
return str;
}
视频里用的VC6,所以sendto的第二个参数老师直接传递的一个CString类的对象,但是我在vs2013中必须要const char *类型,于是我按网上的方法定义了一个string CStringToString(CString cstr)函数。然后单步调试,发现sendto时 _s 指向内容正确。然后我又在接收端插入断点调试
LRESULT CChatDlg::OnRecvData(WPARAM wParam, LPARAM lParam)
{
string send = (char*)lParam;
CString str = (TCHAR*)send.c_str();
TCHAR tempBuf[300] = { 0 };
_stprintf_s(tempBuf, _T("%hs"), str.GetBuffer(str.GetLength()));
CString str1(tempBuf);
CString strTemp("");
GetDlgItemText(IDC_EDIT_RECV, strTemp);
str1 += "\r\n";
str1 += strTemp;
SetDlgItemText(IDC_EDIT_RECV, str1);
return true;
}
结果出现错误提示卡

研究了一下午,实在是走投无路了,望大神们不吝赐教;
------解决思路----------------------
提示很清楚了 BUFF 太小
传递参数时强制转换一下即可, 其它的转换都不要
(const char*)(LPCTSTR)str,
str.GetLength()*sizeof(TCHAR)
------解决思路----------------------
你的buffer太小了,发送的字符串超过了你的发送数据空间等。需要检查一下长度
------解决思路----------------------
这里涉及的是“码制”转换,不是位置转换,你这么转换ASCII可以,转汉字当然不行。
转换函数供参考
具体应用例程请自行下载:http://download.****.net/download/wxhxj0268/4448841
我是照着孙鑫老师的视频做的一个聊天室程序,发送英文没问题,中文却出现很多问题啊
void CChatDlg::OnBnClickedBtnSend()
{
DWORD ipaddr;
((CIPAddressCtrl*)GetDlgItem(IDC_IPADDRESS3))->GetAddress(ipaddr);
SOCKADDR_IN addrSend;
addrSend.sin_addr.S_un.S_addr = htonl(ipaddr);
addrSend.sin_family = AF_INET;
addrSend.sin_port = htons(6000);
CString strsend;
string str;
const char* _s;
GetDlgItemText(IDC_EDIT_SEND, strsend);
str = CStringToString(strsend);
_s = str.c_str();
sendto(m_socket,_s,strsend.GetLength()+1,0,
(SOCKADDR*)&addrSend, sizeof(SOCKADDR));
SetDlgItemText(IDC_EDIT_SEND, TEXT(""));
// TODO: 在此添加控件通知处理程序代码
}
string CStringToString(CString cstr)
{
size_t i;
string str;
setlocale(LC_ALL, "chs");
wchar_t wch[255];
char temp[255];
wcscpy_s(wch, cstr.GetString());
wcstombs_s(&i, temp, wch, 254);
str.append(temp);
return str;
}
视频里用的VC6,所以sendto的第二个参数老师直接传递的一个CString类的对象,但是我在vs2013中必须要const char *类型,于是我按网上的方法定义了一个string CStringToString(CString cstr)函数。然后单步调试,发现sendto时 _s 指向内容正确。然后我又在接收端插入断点调试
LRESULT CChatDlg::OnRecvData(WPARAM wParam, LPARAM lParam)
{
string send = (char*)lParam;
CString str = (TCHAR*)send.c_str();
TCHAR tempBuf[300] = { 0 };
_stprintf_s(tempBuf, _T("%hs"), str.GetBuffer(str.GetLength()));
CString str1(tempBuf);
CString strTemp("");
GetDlgItemText(IDC_EDIT_RECV, strTemp);
str1 += "\r\n";
str1 += strTemp;
SetDlgItemText(IDC_EDIT_RECV, str1);
return true;
}
结果出现错误提示卡
研究了一下午,实在是走投无路了,望大神们不吝赐教;
------解决思路----------------------
提示很清楚了 BUFF 太小
传递参数时强制转换一下即可, 其它的转换都不要
(const char*)(LPCTSTR)str,
str.GetLength()*sizeof(TCHAR)
------解决思路----------------------
你的buffer太小了,发送的字符串超过了你的发送数据空间等。需要检查一下长度
------解决思路----------------------
这里涉及的是“码制”转换,不是位置转换,你这么转换ASCII可以,转汉字当然不行。
转换函数供参考
// Unicod To ANSI转换
int CUDPcommThread::UnicodToAnsi(CString str,char* buff)
{
int len=0;
// UNICODE编码 转换成 ANSI编码
len = ::WideCharToMultiByte(CP_ACP, NULL, str,
str.GetLength(), NULL, 0, NULL, NULL); // 取字串长度
::WideCharToMultiByte(CP_ACP, NULL, str, str.GetLength(),
buff, len, NULL, NULL);
buff[len++]=0x00; // 写字串尾部结束标志
return len; // 转换长度
}
具体应用例程请自行下载:http://download.****.net/download/wxhxj0268/4448841