BCB 如何分割中文bcb字符串操作

Char, String 和 Byte 等类型间的转换和编码 | 小谢的小站
TearSnow Fan
我一句话都不说……
您当前位置 :
>> Char, String 和 Byte 等类型间的转换和编码
Char, String 和 Byte 等类型间的转换和编码
这篇文章的标题看似简单,那就先从简单的说起。众所周知:
1、char 是字符类型;
2、string 是字符串类型;
两者都是及其常用数据类型。虽然一字之差,但是有本质区别:
1、char 在C++中是基础类型,在C#中是值类型(Value Type)。因此,一个 char 类型的对象所占用的控件总是确定的(不要认为是1个字节!Byte才是)。在 C++中,一个char变量可能会是1个字节,也可能是2个字节,这取决于它是否是Unicode Char(也就是所谓的wchar_t)。然而在C#中,它永远是2个字节(没错,是永远,因为其定义就是16位Unicode字符,详见)。
2、string 是一个模板类(C++),也就是一个class了。在C#中,string是引用类型(Reference Type,即使在某些方面有一定值类型的特点)。因此,string对象占用的空间是可变的,理论上只受内存限制,也无法通过 sizeof 来取得的(sizeof 是C++和C#中中的作用一样)。
其用法当然也是众所周知的:
1、char 类型用单引号和一个字符来表示,例如: 'A' ,或者 '谢' 。那么要表示多个字符怎么办,就用字符数组 char [] 就可以了。
这里还需要注意一个问题,就是C++里面将一个汉字赋值给一个char类型变量会丢失信息(因为其只占用1个字节),而应该用wchar_t类型。
2、string 类型用双引号表示,例如:"你好再见。"
下面要开始探讨转换了。
1、char 类型虽然说是字符类型,但是可以隐式或者显式地转换为short, int, long 等整数类型(为什么需要显示转换呢?在下面会详细讨论)。例如:
char c1 = 'A';
Console.WriteLine((short) c1);
//输出为 65
char c2 = (char) 97;
Console.WriteLine(c2);
//c2值为 'a'
这两个值相信很多人都能背下来:大写A的ASCII编码值为65,小写a为97。注意一个问题,在C#中,Char的编码是Unicode,根本不是什么ASCII,因为定长16位的原因,甚至也不能说“兼容ASCII”,但好在这些ASCII字符的数值起码还是一样的。
想到点别的顺便废话一下,想说在Excel中的两个函数Char()和Code():
=CHAR(97) 会返回“a"
=CHAR(98) 会返回“b"
=Code(“a") 会返回“97"
=Code(“b") 会返回“98"
以此类推……
2、char 类型既然可以用来存储数值,就必然有 signed 和 unsigned 之分。在C++中,
signed char 是8位有符号数,取值范围 -128 到 +127;
unsigned char 是8位无符号数,取值范围从 0 到 255 。
但是在C#中,Char 被规定为无符号的,Byte 类型也是无符号的:
a)Byte 变量以无符号的 8 位(1 个字节)数字的形式存储,取值范围为 0 到 255,因此Byte 数据类型可以隐式转换为 short、int、long、Single、Double 或 Decimal 数据类型(好像是废话)。
b)Char 变量以无符号的 16 位(2 个字节)数字的形式存储,取值范围为 0 到 65535(因为其用于表示本来是用来代表 Unicode 字符,Unicode 哪来的负数)。所以重新考虑上面的几种 Byte 可以隐式转换成的数据类型,由于short是16位有符号数,不能完全覆盖 Char 所标示的数值范围,因此 Char 是不能够隐式地转换为 short 类型的。强制转换当然是可以的,但是要自己承担System.OverflowException的风险。这是很显然的,考虑下其占用的存储空间就能够明白,所以建议用Int16,Int32,Int64代替short,int和long的写法。
那么至于string类型,它需要占多少空间呢?
前面已经说了,string的大小是不可以通过sizeof来获得的。如果尝试通过sizeof取得string的大小,会遇到编译错误。理论上字符串中每个字符都和Char一样,应该占2个字节,而且需要考虑string的最后还有一个特殊的字符,是不可见的'\0',也占2个字节。(其实由于string是引用类型,考察其本身在堆上所占空间其实意义不大)
下面说说字符串和字符数组之间的转换,也就是 string 和 char []。
1、string 转换成 Char[] 需要用到 String 的 ToCharArray()方法,例如
string ss=&abcdefg&;
char[] cc=ss.ToCharArray();
//实际上多数情况下不需要这么做,因为使用ss[N]可以访问指定下标的字符对象。
2、Char[] 转换成string,就更简单了,可以直接用string的构造函数
//char [] cc 定义同前段代码
string s=new string(cc);
前面说的是字符串和字符数组之间的转换,下面说说字符串和字节数组间怎么转换。
虽然只差一个字,但区别可就大了,因为这涉及编码……
请先看下面的代码:
static void Main(string[] args)
string input = &你好,再见。&;//逗号为半角字符,句号为全角字符。
Console.WriteLine(input);
//测试Default编码
Console.WriteLine(&Default Encoding: {0}&, Encoding.Default.EncodingName);
byte[] bytesDefault = Encoding.Default.GetBytes(input);
Console.WriteLine(&Default Encoding Size: &+bytesDefault.Length);//返回11,每个汉字占2字节,半角逗号占1个字节
//测试Unicode(就是UTF16)
byte[] bytesUnicode = Encoding.Unicode.GetBytes(input);
Console.WriteLine(&Unicode/UTF16 Encoding Size: &+bytesUnicode.Length);//返回12,所有字符都用两个字节
//测试UTF8
byte[] bytesUTF8 = Encoding.UTF8.GetBytes(input);
Console.WriteLine(&UTF8 Encoding Size: & + bytesUTF8.Length);//返回16,所有字符都用两个字节
//测试UTF32
byte[] bytesUTF32 = Encoding.UTF32.GetBytes(input);
Console.WriteLine(&UTF32 Encoding Size: & + bytesUTF32.Length);//返回16,所有字符都用两个字节
//测试ASCII
byte[] bytesASCII = Encoding.ASCII.GetBytes(input);
Console.WriteLine(&ASCII Encoding Size: & + bytesASCII.Length);//返回6,所有字符都用一个字节(汉字和全角句号没有真正编码成功)
Console.WriteLine(&ASCII编码复原:{0}&,Encoding.ASCII.GetString(bytesASCII));
//从字符串生成Encoding对象,以及Unicode编码的WebName(utf-16)
Console.WriteLine(&Encoding.GetEncoding(\&unicode)\&).WebName: {0}&,System.Text.Encoding.GetEncoding(&uniCode&).WebName);
Console.Read();
结果如图:
关于几种编码的介绍,详见《》一文。上面的代码说明了以下几个问题:
1、如果操作系统的Current System Locale设置为“中国,简体中文”Chinese (Simplified,PRC),则默认的编码 System.Encoding.Default 就是"gb2312"。
如果你想得到这个编码,除了用System.Encoding.Default以外,还可以:
System.Text.Encoding.GetEncoding(936)
System.Text.Encoding.GetEncoding("gb2312")
当然,如果确定要使用GB2312编码,用后两个要比Default靠谱多了。
2、Encoding对象的 GetBytes() 方法和 GetString() 方法提供了 string 和 Byte[] 之间的转换,
3、可以认为 Unicode 编码就是 UTF-16,在Encoding.GetEncoding()方法参数中使用"unicode"和"utf-16"的名称是完全一样的,这个方法也不区分字符串的大小写,但是注意不能省略连字符,例如将utf-16写作utf16将无法识别。
4、ASCII编码是不能用于保存中文字符的,不要奢望系统会用ASCII字符当容器来封装Unicode一类的。但是诡异的是,居然也不抛出个异常……
还有一种比较特殊的转换也经常能够见到,尤其是HTTP协议中,这就是Base64编码。
Base64是网络上最常见的用于传输8-bits字节代码的编码方式之一,具体可以查看RFC2045~RFC2049,上面有MIME的详细规范。Base64编码可用于在HTTP环境下传递较长的标识信息。例如,在Java Persistence系统Hibernate中,就采用了Base64来将一个较长的唯一标识符(一般为128-bit的UUID)编码为一个字符串,用作HTTP表单和HTTP GET URL中的参数。在其他应用程序中,也常常需要把二进制数据编码为适合放在URL(包括隐藏表单域)中的形式。此时,采用Base64编码不仅比较简短,同时也具有不可读性,即所编码的数据不会被人用肉眼所直接看到。
这么看来,base64编码需要解决的主要问题是把 Byte[] 转换为 Base64 编码的 String,以及复原(将 Base64String 恢复为 Byte [])。这可以通过 System.Convert静态类中的静态方法类实现。
详见MSDN:。
最后说个与string 有关的技巧:
由于C#中,string是不可变的。在动态构造字符串的时候(例如:result = result+" Test " ),其实会产生一个新的字符串,原有的result还会保留,新创建的一个的result是旧的result和“Test”连起来的结果。所以,为了更好的使用资源,应该使用StringBuilder。其Append()方法带有多种参数,可以对字符串进行各种组合操作,最后用其 ToString() 输出即可。
最后附个表,不要忘记有一些字符是比较特殊的,也就是所谓的“转义字符”。在使用char或者string的时候,都需要转义。
回退:向后退一格
换行,光标到下行行首
回车,光标到本行行首
\ddd: 三位八进制
\xhh: 二位十六进制
空字符(NULL),什么都不做。换行只是换一行,不改变光标的横坐标;回车只是回到行首,不改变光标的纵坐标。
参考资料:
[1] 博客园:(作者:陈希章)
本文固定链接:
【上一篇】【下一篇】
您可能还会对这些文章感兴趣!
最新日志热评日志随机日志
官方微信扫一扫
日志总数:151 篇
评论总数:290 篇
分类总数:9 个
标签数量:251 个
链接总数:10 个
建站日期:
运行天数:1522 天
最后更新:
如果您觉得本站的内容对您有帮助,非要感谢一下不可,那么请给小谢捐赠。文/图 灰狐(Bink && E.S.T)===================================&俗话说的好,不会的黑客就不是好黑客(我会编程,但我也不是黑客,因为我是个——员,哈哈)。今天呢,我们就亲自动手打造一个专属于自己的小工具。 我们要做的是一个QQ炸弹,其实这个工具的威力并不是很大,顶多只能和好友聊天的时候骚扰一下。思路很简单,就是通过程序不停地模拟按键“Ctrl+Enter”自动发送消息,不过当我们做成的时候,心里自然也会有那么一种满足和喜悦。 编程工具的选择很重要,像这样的小东东如果用VC来做,那真不是一般的麻烦。什么?你说Delphi很快?那倒是,不过会Pascal的肯定没会C的人多吧。就以我们学校来说,基本对于所有的理工专业都是必修课。对于快速的可视化开发,BCB当然是第一选择,因为兼具了VC与Delphi共同优点的武林第一神兵利器要隆重出场了,让我们用热烈的掌声欢迎:Borland C++ Builder 6.0(简称BCB)。 程序详细思路:首先打开与好友的聊天窗口,程序通过窗口名搜索得到窗口句柄,下一步是自动将要发送的语句拷贝到剪贴板中,然后激活聊天窗口让其得到输入焦点,最后就是通过循环不断地模拟按键Ctrl+V和Ctrl+Enter了。 启动BCB 6.0,会默认自动新建一个Application,在窗体上放一个PageControl控件(在Win32页中),将其Align属性设置为alClient,新建一个TabSheet(很多人都说怎么也找不到这个控件,其实新建它的方法是右键点击PageControl,然后New Page就OK了),将其Caption属性设置为“轰炸好友”,其余控件就根据图1来放吧。从上到下三个编辑框(Edit控件)的Name属性依次为NcikNameEdit、FrequentEdit和TimesEdit,最下面是个Memo控件,Name属性设置为WordMemo。好了,下面我们就用代码说话吧(代码侧重程序实现原理,有所删减,完整工程及代码文件已经打包提供)。 &图1
首先,我们要找到聊天窗口,其实现代码如下。
char WindowBuffer[MAX_PATH]; //存放窗口名的缓冲区 sprintf(WindowBuffer,"与 %s 聊天中",NickNameEdit-&Text); HANDLE hWindow = FindWindow(NULL,WindowBuffer); //查找窗口 if( hWindow == NULL ) { Show("抱歉,没有找到此聊天窗口!");
这样,我们就得到了聊天窗口的句柄h,然后就可以开工编写轰炸的代码了。
this-&Hide();&&&&&&&& //隐藏窗口,没必要显示 for(int i=1;i&=StrToInt(TimesEdit-&Text);i++) {//因为编辑框里面默认都是String类型,所以我们要通过StrToInt将轰炸次数转换成int型才能在循环中使用它 WordMemo-&SelectAll();&&&&&&& //选中全部语句 WordMemo-&CopyToC&&&&&&& //将其拷贝到剪贴板 SetForegroundWindow(hWindow); //将聊天窗口激活使其得到键盘焦点 StartBomb(); //调用炸弹函数开始轰炸 Sleep(StrToInt(FrequentEdit-&Text)); //暂停一段时间后继续下一个循环 } this-&Show();&&&&&&&& //执行完毕后显示窗口
其中,StartBomb()函数的代码如下。
void __fastcall TMainForm::StartBomb(void) { keybd_event(VK_CONTROL,0,0,0); //模拟按下Ctrl键 keybd_event(V,V,0,0);&&&&&&&& //模拟按下V键,必须为大写 keybd_event(V,V,KEYEVENTF_KEYUP,0); //模拟放开V键 keybd_event(VK_CONTROL,0,KEYEVENTF_KEYUP,0); //模拟放开Ctrl键 keybd_event(VK_CONTROL,0,0,0); keybd_event(VK_RETURN,0,0,0); //模拟按下Enter键 keybd_event(VK_RETURN,0,KEYEVENTF_KEYUP,0); keybd_event(VK_CONTROL,0,KEYEVENTF_KEYUP,0); }
这样一个QQ炸弹的就已经出炉了,记住,它只是个模型。如果要做好一个的话,绝不仅仅是可以用了就成,我们还需要考虑用户的友好性、程序的完善性等等,限于篇幅就不多废话了。由于时间限制,我做这个测试炸弹的时候也没有更多地进行优化,对于“炸QQ群”的功能与以上原理是一样的,只要能找到其窗口就可以了。关于托盘图标,我们可以使用BCB自带的TrayIcon控件(在Samples页),然后简单设置一下属性就可以使用了,很方便。 这个程序有一个BUG,就是编码问题。如果要发送的字符是中文的话,它发送到聊天窗口中就变成了乱码,限于时间原因,我没能找出真正的解决方法。不过在尝试解决它的过程中却学到了操作剪贴板的方法,因为CopyToClipboard()只是BCB中的一个成员函数,在其他地方不能直接使用,我们可以通过一系列的函数来实现这种功能,下面给出一段实例代码。
AnsiS&&&&&&& //保存要拷贝的字符 OpenClipboard(NULL); //打开系统剪贴板 EmptyClipboard(); //使用之前要先清空剪贴板 HGLOBAL hClipD& //分配一段内存,大小等于要复制的的大小 hClipData = //protect/201009/GlobalAlloc(GMEM_DDESHARE,buffer.Length()+1); char *pchD&& //内存控制句柄加锁 pchData = /network/protect/201009/(char *)GlobalLock(hClipData); strcpy(pchData,buffer.c_str());& //将变量值赋给全局内存 GlobalUnlock(hClipData);& //给内存控制句柄解锁 SetClipboardData(CF_TEXT,hClipData); //通过全局内存句柄将数据以相应的格式放进剪贴板 CloseClipboard(); //使用完后记得关闭剪贴板
这段代码通常用来完成进程间通信等功能,由于其使用简单,容易理解,所以用处还是比较广泛的。 最后说一点有关BCB的小。 1)默认情况下,你会发现它生成的可执行程序很小,但却不能在没有安装BCB或Delphi的机器上运行,此时我们需要设置一下,在“project-&Options-&Compiler”中点击“Release”,在“project-&Options-&s”中取消“Builder with runtime packages”的勾,在“project-&Options-&Linker”中取消“Use dynamic RTL”前的勾。 2)更换BCB自带的图标,点击“Project-&Options-&Application-&LoadIcon”,目标必须是ico格式。 3)如果你是BCB的初学者的话,推荐《C++ Builder初学问与答》这一系列,基本上对BCB中所有的常用控件都做了详细的说明,非常有用温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
LOFTER精选
网易考拉推荐
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
CompareText
比较两个AnsiString字符串,函数原型如下:int __fastcall CompareText(const AnsiString S1, const AnsiString S2);
将指定的AnsiString字符串转换为小写形式,函数原型如下:AnsiString __fastcall LowerCase(const AnsiString S);
为字符串分配指定字节的内存,并返回内存指针,函数原型如下:char * __fastcall StrAlloc(Cardinal Size);
StrBufSize
返回*Str所指向内存的大小,函数原型如下:Cardinal __fastcall StrBufSize(const char * Str);
连接两个字符串,并返回目的字符串指针,函数原型如下:char * __fastcall StrCat(char * Dest, const char * Source);
两个字符串相到比较,返回比较的结果,函数原型如下:int __fastcall StrComp(const char * Str1, const char * Str2);
将源字符串拷贝到目的字符串中,函数原型如下:char * __fastcall StrCopy(char * Dest, const char * Source);
将源字符串拷贝到目的字符串中,并返回目的字符串结尾指针,函数原型如下:char * __fastcall StrECopy(char * Dest, const char * Source);
返回字符串结尾指针,函数原型如下:char * __fastcall StrEnd(const char * Str);
两个字符串相互比较(不论大小写),返回比较的结果,函数原型如下:int __fastcall StrIComp(const char * Str1, const char * Str2);
将指定数目的源字符串连接到目的字符串,并返回目的字符串指针,函数原型如下:char * __fastcall StrLCat(char * Dest, const char * Source, Cardinal MaxLen);
对两个字符串指定数目的字符进行比较操作,函数原型如下:int __fastcall StrLComp(const char * Str1, const char * Str2, Cardinal MaxLen);
将源字符串指定数目的字符拷贝到目的字符串中,并返回目的字符串指针,函数原型如下:char * __fastcall StrLCopy(char * Dest, const char * Source, Cardinal MaxLen);
返回字符串的长度,函数原型如下:Cardinal __fastcall StrLen(const char * Str);
将字符串转换为小写形式,函数原型如下:char * __fastcall StrLower(char * Str);
从源字符串向目的字符串拷贝指定数目的字符,函数原型如下:char * __fastcall StrMove(char * Dest, const char * Source, Cardinal Count);
在堆中为指定字符串分配空间,并将字符串拷贝到此空间中,函数原型如下:char * __fastcall StrNew(const char * Str);
将指定的字符串转换为AnsiString类型字符串对象,函数原型如下:AnsiString __fastcall StrPas(const char * Str);
将AnsiString类型的源字符串拷贝到目的字符串中,并返回目的字符串指针,函数原型如下:char * __fastcall StrPCopy(char * Dest, const AnsiString Source);
将源字符串(AnsiString类型)指定数目的字符拷贝到目的字符串中,并返回目的字符串指针,函数原型如下:char * __fastcall StrPLCopy(char * Dest, const AnsiString Source, Cardinal MaxLen);
在Strl所指定的字符串中寻找Str2所指定的子字符串,并返回Str2在Str2中第一个子字符的指针,函数原型如下:char * __fastcall StrPos(const char * Str1, const char * Str2);
在指定的字符串中寻找特定的字符,并返回字符串中最后一个特定字符的指针,函数原型如下:char * __fastcall StrRScan(const char * Str, char Chr);
在指定的字符串中寻找特定的字符,并返回字符串中第一个特定字符的指针,函数原型如下:char * __fastcall StrScan(const char * Str, char Chr);
将字符串转换为大写形式,函数原型如下:char * __fastcall StrUpper(char * Str);
将指定的AnsiString字符串转换为大写形式,函数原型如下:AnsiString __fastcall UpperCase(const AnsiString S);
阅读(2961)|
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
loftPermalink:'',
id:'fks_',
blogTitle:'BCB函数集(字符串操作)',
blogAbstract:'函数名称\nCompareStr\n\n函数说明\n比较两个AnsiString字符串,函数原型如下:int __fastcall CompareStr(const AnsiString S1, const AnsiString S2);\n\n\n\n\n\n\n函数名称\nCompareText',
blogTag:'',
blogUrl:'blog/static/',
isPublished:1,
istop:false,
modifyTime:0,
publishTime:0,
permalink:'blog/static/',
commentCount:1,
mainCommentCount:1,
recommendCount:0,
bsrk:-100,
publisherId:0,
recomBlogHome:false,
currentRecomBlog:false,
attachmentsFileIds:[],
groupInfo:{},
friendstatus:'none',
followstatus:'unFollow',
pubSucc:'',
visitorProvince:'',
visitorCity:'',
visitorNewUser:false,
postAddInfo:{},
mset:'000',
remindgoodnightblog:false,
isBlackVisitor:false,
isShowYodaoAd:false,
hostIntro:'',
hmcon:'1',
selfRecomBlogCount:'0',
lofter_single:''
{list a as x}
{if x.moveFrom=='wap'}
{elseif x.moveFrom=='iphone'}
{elseif x.moveFrom=='android'}
{elseif x.moveFrom=='mobile'}
${a.selfIntro|escape}{if great260}${suplement}{/if}
{list a as x}
推荐过这篇日志的人:
{list a as x}
{if !!b&&b.length>0}
他们还推荐了:
{list b as y}
转载记录:
{list d as x}
{list a as x}
{list a as x}
{list a as x}
{list a as x}
{if x_index>4}{break}{/if}
${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}
{list a as x}
{if !!(blogDetail.preBlogPermalink)}
{if !!(blogDetail.nextBlogPermalink)}
{list a as x}
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
{list a as x}
{var first_option =}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if}&&“${b[voteToOption_index]}”&&
{if (x.role!="-1") },“我是${c[x.role]}”&&{/if}
&&&&&&&&${fn1(x.voteTime)}
{if x.userName==''}{/if}
网易公司版权所有&&
{list x.l as y}
{if defined('wl')}
{list wl as x}{/list}

我要回帖

更多关于 bcb 解析json字符串 的文章

 

随机推荐