带汉字的CString在Unicode编码下如何转换成char *

time_is_life 2014-08-17 10:50:04
其中CString存的是从界面上获取的汉字。
我用了如下的代码:

CString str, str1;
GetDlgItem( IDC_SENDTEXT ) -> GetWindowText(str);
char* pBuff = W2A(str);


用过CT2A. W2A, wcstombs,WideCharToMultiByte 都不行。得到的都是乱码。
到底该怎么转?请指教,谢谢。
...全文
353 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
辰岡墨竹 2014-08-22
  • 打赏
  • 举报
回复
引用 8 楼 time_is_life 的回复:
[quote=引用 5 楼 Bokutake 的回复:] 你的逻辑有问题。 网络传输char *并不是要求你把文字也转换为ANSI编码。网络传输的实际是字节流。 所以你把CString的内容直接拷贝到一个char数组里,或者强制转换也可以。 if( ::send( s, (const char *) (LPCTSTR) str, (str.GetLength() + 1) * sizeof(TCHAR) , 0 ) != SOCKET_ERROR ) 加不加一取决于你是不是用其它的结构传递了字符串长度,如果那样,就可以省略掉。
用如下的代码只能传过去第一个字符,汉字是一个乱码。

		if( ::send( s, (const char *)((LPCTSTR)str), (str.GetLength() + 1) * sizeof(TCHAR), 0 ) != SOCKET_ERROR )

[/quote] 你服务器接收的时候不要再用A2W转码啊。保持编码,你的转换是多此一举。
  • 打赏
  • 举报
回复
网络传输过程中应保持编码一直
vcf_reader 2014-08-21
  • 打赏
  • 举报
回复
既然是网络传输,根本不需要转码,多此一举
赵4老师 2014-08-18
  • 打赏
  • 举报
回复
对电脑而言没有乱码,只有二进制字节;对人脑才有乱码。啊 GBK:0xB0 0xA1,Unicode-16 LE:0x4A 0x55,Unicode-16 BE:0x55 0x4A,UTF-8:0xE5 0x95 0x8A
void HexDump(char *buf,int len,int addr) {
    int i,j,k;
    char binstr[80];

    for (i=0;i<len;i++) {
        if (0==(i%16)) {
            sprintf(binstr,"%08x -",i+addr);
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
        } else if (15==(i%16)) {
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
            sprintf(binstr,"%s  ",binstr);
            for (j=i-15;j<=i;j++) {
                sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
            }
            printf("%s\n",binstr);
        } else {
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
        }
    }
    if (0!=(i%16)) {
        k=16-(i%16);
        for (j=0;j<k;j++) {
            sprintf(binstr,"%s   ",binstr);
        }
        sprintf(binstr,"%s  ",binstr);
        k=16-k;
        for (j=i-k;j<i;j++) {
            sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
        }
        printf("%s\n",binstr);
    }
}
HUSTYZHY 2014-08-18
  • 打赏
  • 举报
回复
WCHAR*
worldy 2014-08-18
  • 打赏
  • 举报
回复
发送过程数据是不会被改变的,发送的是什么编码接受也是什么编码,只有发送端和接收端编码不同才需要转换
zgl7903 2014-08-18
  • 打赏
  • 举报
回复
转换代码页用 936 WideCharToMultiByte( 936, ……
ulwfnh1100 2014-08-18
  • 打赏
  • 举报
回复
看你的代码应该没有问题呀,我都写代码测试过。
time_is_life 2014-08-17
  • 打赏
  • 举报
回复
引用 3 楼 chenlycly 的回复:
使用WideCharToMultiByte转换一下即可:

void CopyCStringTToChar( char* pchDest, const CString& strSrc, int nDestLen )
{
	if ( pchDest == NULL )
	{
		return;
	}

#ifdef _UNICODE // 使用宽字节
	{
		WCHAR* pWStrSRc = const_cast<CString&>(strSrc).GetBuffer(0);
		int nTmplen = WideCharToMultiByte( CP_ACP, 0, pWStrSRc, -1, NULL, 0, NULL, NULL );
		char* pTemp = new char[nTmplen+1];
		memset( pTemp, 0, nTmplen+1 );
		WideCharToMultiByte( CP_ACP, 0, pWStrSRc, -1, pTemp, nTmplen+1, NULL, NULL );

		int nLen = strlen(pTemp);
		if( nLen + 1 > nDestLen )				
		{													
			strncpy( pchDest, pTemp, nDestLen-1 );		
			pchDest[nDestLen-1] = 0;					    
		}													
		else												    
		{													
			strcpy( pchDest, pTemp );							
		}

		delete []pTemp;
	}
#else // 使用窄字节
	{
		int nSrcLen = strSrc.GetLength();

		if( nSrcLen + 1 > nDestLen )				
		{													
			strncpy( pchDest, strSrc, nDestLen-1 );		
			pchDest[nDestLen-1] = 0;					    
		}													
		else												    
		{													
			strcpy( pchDest, strSrc );							
		}
	}
#endif
}
试过了,输入"汉字测试",结果变成了"ºº×"
dvlinker 2014-08-17
  • 打赏
  • 举报
回复
使用WideCharToMultiByte转换一下即可:

void CopyCStringTToChar( char* pchDest, const CString& strSrc, int nDestLen )
{
	if ( pchDest == NULL )
	{
		return;
	}

#ifdef _UNICODE // 使用宽字节
	{
		WCHAR* pWStrSRc = const_cast<CString&>(strSrc).GetBuffer(0);
		int nTmplen = WideCharToMultiByte( CP_ACP, 0, pWStrSRc, -1, NULL, 0, NULL, NULL );
		char* pTemp = new char[nTmplen+1];
		memset( pTemp, 0, nTmplen+1 );
		WideCharToMultiByte( CP_ACP, 0, pWStrSRc, -1, pTemp, nTmplen+1, NULL, NULL );

		int nLen = strlen(pTemp);
		if( nLen + 1 > nDestLen )				
		{													
			strncpy( pchDest, pTemp, nDestLen-1 );		
			pchDest[nDestLen-1] = 0;					    
		}													
		else												    
		{													
			strcpy( pchDest, pTemp );							
		}

		delete []pTemp;
	}
#else // 使用窄字节
	{
		int nSrcLen = strSrc.GetLength();

		if( nSrcLen + 1 > nDestLen )				
		{													
			strncpy( pchDest, strSrc, nDestLen-1 );		
			pchDest[nDestLen-1] = 0;					    
		}													
		else												    
		{													
			strcpy( pchDest, strSrc );							
		}
	}
#endif
}
time_is_life 2014-08-17
  • 打赏
  • 举报
回复
引用 1 楼 worldy 的回复:
如果编译选项确实是unicode,那么 pBuff使用TextOutA函数输出看看,应该不会乱码
谢谢回复,我是用网络传输。

		size_t len = str.GetLength();
		if( ::send( s, pBuff, len, 0 ) != SOCKET_ERROR )
然后在服务器端这样接收:

LRESULT CTCPClientDlg::OnSocket(WPARAM wParam, LPARAM lParam)
{
	USES_CONVERSION;
	// TODO: Add your control notification handler code here
	char cs[100] = {0};
	if( lParam == FD_READ )
	{
		CString num = TEXT("");
		recv( s, cs, 100, NULL );
		CString recvText = A2W(cs);
		GetDlgItem( IDC_TEXT ) -> GetWindowText( num );
		num += TEXT("服务器说:\r\n");
		num += recvText;
		GetDlgItem( IDC_TEXT ) -> SetWindowText( num );
	}

	return 0;
}
英文字符是可以的,汉字就显示问号.
worldy 2014-08-17
  • 打赏
  • 举报
回复
如果编译选项确实是unicode,那么 pBuff使用TextOutA函数输出看看,应该不会乱码
zwfgdlc 2014-08-17
  • 打赏
  • 举报
回复
CString str, str1;
GetDlgItem( IDC_SENDTEXT ) -> GetWindowText(str);
//char* pBuff = W2A(str); //这个多余的不用转换
size_t len =( str.GetLength()+1)*sizeof(TCHAR);
if( ::send( s, pBuff, len, 0 ) != SOCKET_ERROR )



LRESULT CTCPClientDlg::OnSocket(WPARAM wParam, LPARAM lParam)
{
	USES_CONVERSION;
	// TODO: Add your control notification handler code here
	WCHAR cs[100] = {0};
	if( lParam == FD_READ )
	{
		CString num = TEXT("");
		recv( s, (char*)cs, 100, NULL );
		//CString recvText = A2W(cs); 也不用转换
               CString recvText = cs;
		GetDlgItem( IDC_TEXT ) -> GetWindowText( num );
		num += TEXT("服务器说:\r\n");
		num += recvText;
		GetDlgItem( IDC_TEXT ) -> SetWindowText( num );
	}

	return 0;
}

time_is_life 2014-08-17
  • 打赏
  • 举报
回复
引用 5 楼 Bokutake 的回复:
你的逻辑有问题。 网络传输char *并不是要求你把文字也转换为ANSI编码。网络传输的实际是字节流。 所以你把CString的内容直接拷贝到一个char数组里,或者强制转换也可以。 if( ::send( s, (const char *) (LPCTSTR) str, (str.GetLength() + 1) * sizeof(TCHAR) , 0 ) != SOCKET_ERROR ) 加不加一取决于你是不是用其它的结构传递了字符串长度,如果那样,就可以省略掉。
用如下的代码只能传过去第一个字符,汉字是一个乱码。

		if( ::send( s, (const char *)((LPCTSTR)str), (str.GetLength() + 1) * sizeof(TCHAR), 0 ) != SOCKET_ERROR )

zwfgdlc 2014-08-17
  • 打赏
  • 举报
回复
	
size_t len = str.GetLength()*sizeof(TCHAR);
if( ::send( s, pBuff, len, 0 ) != SOCKET_ERROR )
辰岡墨竹 2014-08-17
  • 打赏
  • 举报
回复
char *和ANSI编码字符串没有必然联系。网络通信接口里char *只是指向一个数组罢了。
辰岡墨竹 2014-08-17
  • 打赏
  • 举报
回复
你的逻辑有问题。 网络传输char *并不是要求你把文字也转换为ANSI编码。网络传输的实际是字节流。 所以你把CString的内容直接拷贝到一个char数组里,或者强制转换也可以。 if( ::send( s, (const char *) (LPCTSTR) str, (str.GetLength() + 1) * sizeof(TCHAR) , 0 ) != SOCKET_ERROR ) 加不加一取决于你是不是用其它的结构传递了字符串长度,如果那样,就可以省略掉。

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧