CString,UNICODE,如此头痛的问题!

赖勇浩 2004-11-23 12:47:23
当CString装的是中文时用CString::Left(1)得到的却并不是第一个中文字,使用CString::Left(2)得到第一个中文字,但装的是英文时却得到两个字母,真的让人哭笑不得啊,我怎么样才能得到一个字条串的第一个字,如果是"中文"我就得到'中'字,如果是"china"我就得到'c'?

可能使用STL的base_string<wchar_t>可以解决,但一个编辑框只可以和CString对象绑定啊,怎么进行CString到base_string<wchar_t>的转换呢?

谢谢大家.
...全文
1434 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
赖勇浩 2004-11-24
  • 打赏
  • 举报
回复
楼上的函数非常有用!结贴啦.
pomelowu 2004-11-23
  • 打赏
  • 举报
回复
好像是CString的Bug
3m2u 2004-11-23
  • 打赏
  • 举报
回复
瞎写的果然有问题,少括号,重新改一下:

CString MyLeft(CString&s,int n)
{
CString sRet="";
int nPos=0;
while(nPos<s.GetLength() && n)
{
if(s.GetAt(nPos)<0){
sRet=sRet+s.GetAt(nPos)+s.GetAt(nPos+1);
nPos++;
}else
sRet+=s.GetAt(nPos);
nPos++;
n--;
}
return sRet;
}
3m2u 2004-11-23
  • 打赏
  • 举报
回复
取左面的n个字符(中文算一个)的简单代码 随便写的,没调试

CString MyLeft(CString&s,int n)
{
CString sRet="";
int nPos=0;
while(nPos<s.GetLength() && n){
if(s.GetAt(nPos)<0){
sRet=sRet+s.GetAt(nPos)+s.GetAt(nPos+1);
nPos+=2;
n--;
}else{
sRet+=s.GetAt(nPos);
nPos++;
n--;
}
return sRet;
}
赖勇浩 2004-11-23
  • 打赏
  • 举报
回复
我,我再试试羽战士的方法,但有错,首先是内存泄漏,然后是string似乎是char型的,而不是wchar_t的,

无论如何,谢谢你!
sodangerous 2004-11-23
  • 打赏
  • 举报
回复
判断一个字节是汉字的前一个字节,还是后一个字节
1> 使用IsDBCSLeadByte函数能够判断一个字符是否是双字的第一个字节,试试看:)
2> _ismbslead _ismbstrail
3> GB2312/GBK用的是高位区码(GBK用扩展的区码)+高位位码拼成一个全角字(双字节),由于区码和位码都在128以上,并且没有可靠的算法分辩两个字节(原因下面我会解释),需要准确搜索时,不能随便从中间定位,因为如果错开了一个字节,就会造成乱码,这样诸如二分法之类的算法都不灵了。
当然,如果你是用等宽的编码,比如UNICODE,或GB2312/GBK全汉字字符(英文和标点用全角汉字),就没有上面的问题,WINDOWS内部就用双字节的UNICODE,代价是资源消耗很大,而后一种所有字符都采用全角的情况很少见。
注:GBK是GB2312的扩展,而GB2312最大的问题之一,是区码的码位和位码规则完全一样,原始的GB2312区位,区是从1到94,位也是1到94,护展到机内码是区号+160,位号加160,各占一个字节,因此从理论上来说,在字符串内以字节为单位随机取一个字节开始,没有可靠的算法可以分辩出这个字节是区码还是位码,而它后面的字串也跟着不能确定,于是精确的搜索字串只能老老实实从第一个字节开始扫描,见到第一个128以上的字节就当成汉字的区位,从它开始定位两个一组解析,直到发现第一个ASCII码为止,于是以字节为单位转入ASCII的分析,直到发现一个大于128的字符......这种循环效率低下是肯定的。

pomelowu 2004-11-23
  • 打赏
  • 举报
回复
CEdit是从CWnd派生的,比如IDC_EDIT是这个编辑框的ID:

LPTSTR lpszStr = new char[MAX_LENGTH];
if (!lpszStr)
return FALSE;

memset(lpszStr, 0, MAX_LENGTH);
CEdit pEdit = (CEdit *)GetDlgItem(IDC_EDIT);
pEdit->GetWindowText(lpszStr, MAX_LENGH);

string strData = lpszStr;
scottlai 2004-11-23
  • 打赏
  • 举报
回复
saintl(shengliang) 可行,原理是:
中文字一般是占用两个字节的而且第个字节的ASCII码都是大于127

而英文、英文字符和数字都在32到127之间,所以先判断第一个字节是否在32到127之间,如果不是就再是事大于127,如果大于就把后面的字节也读进来。
赖勇浩 2004-11-23
  • 打赏
  • 举报
回复
以上大家的方法大多试过了,除了羽战士的,不知道怎么用.GetWindowText是一个CWnd的方法,我在哪里调用它?如果我在主框架调用,那得到的是软件左上角的标题啊.不知道怎么回事.

如果大家有空,帮我做一个对话框程序,有两个编辑框一个按钮,当在A框输入一个字符串后按按钮就会在另一个编辑框中显示A框中的字符串的字一个字,中文是一个字,英文是一个字母,然后把那个按钮相关的函数弄上来,相信不止是我,很多人都会非常感谢你的.

微软这么大一个公司怎么一个CString都做得如此不伦不类啊?真是有点失望啊.
pomelowu 2004-11-23
  • 打赏
  • 举报
回复
>可能使用STL的base_string<wchar_t>可以解决,但一个编辑框只可以和CString对象绑定啊,怎么进
>行CString到base_string<wchar_t>的转换呢?

你不需要进行绑定数据啊,要获得数据的时候用
int GetWindowText(
LPTSTR lpszStringBuf,
int nMaxCount
) const;
的重载,再转化为string就方便了啊。
oyljerry 2004-11-23
  • 打赏
  • 举报
回复
一般是取字符,然后判断大小了
saintl 2004-11-23
  • 打赏
  • 举报
回复
你可以先取一个字符,判断一下ASCII码是否为32到127,如果不是,则取两个字符
例如:
有个CString a;
CString temp1;
temp1=a.Left(1);
char* p=temp1.GetBuffer(10);
if(*p >= 32 && *p <=127)
return CString temp1;
else
temp1=a.Left(2);
fisker0303 2004-11-23
  • 打赏
  • 举报
回复
同意 happyparrot(快乐鹦鹉)的方法。
danyueer 2004-11-23
  • 打赏
  • 举报
回复
你可以用Unicode字符串,方法是把原始字符串通过MultiByteToWideChar转换为Unicode字符串,然后进行操作,到输出的时候,用WideCharToMultiByte转换回ANSI字符串。

int MultiByteToWideChar(
UINT CodePage, // code page
DWORD dwFlags, // character-type options
LPCSTR lpMultiByteStr, // string to map
int cbMultiByte, // number of bytes in string
LPWSTR lpWideCharStr, // wide-character buffer
int cchWideChar // size of buffer
);

int WideCharToMultiByte(
UINT CodePage, // code page
DWORD dwFlags, // performance and mapping flags
LPCWSTR lpWideCharStr, // wide-character string
int cchWideChar, // number of chars in string
LPSTR lpMultiByteStr, // buffer for new string
int cbMultiByte, // size of buffer
LPCSTR lpDefaultChar, // default for unmappable chars
LPBOOL lpUsedDefaultChar // set when default char used
);
快乐鹦鹉 2004-11-23
  • 打赏
  • 举报
回复
CString就是这样子。Left始终以字节为单位。即时你使用的是UNICODE码。
判断第1个字符是否大于0x80来判断该字符是否为中文的一部分
NOMADBLUE 2004-11-23
  • 打赏
  • 举报
回复
不如不CString继承并把其Bug函数冲定义一下

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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