大送分:关于字符串处理的菜鸟级问题

yokel 2003-08-05 10:22:53
1.用CString要引入什么头文件呀?老出错
2.哪个处理字符串类好用呀
3.char c1[]="9z按时的sdf";时,c1[2]不是“按”,怎样可以象VB一样能得到“按”的偏移值为2
4.如“hello,。按,the时world!的sdf”这样一个字符串,如何得到其中各个英文单词及其偏移值,一个汉字或标点只算1
...全文
28 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
tigerfox 2003-08-08
  • 打赏
  • 举报
回复
我来了。


code好使了吗?
xiaohedou 2003-08-08
  • 打赏
  • 举报
回复
TO yokel (SOD) :抱歉,你的帖子后来就忘看了.你作一个英文字母ASCII吗表,然后用指针比较就行了.

...... //52个小大写字母
unsigned char uAscii[2*26+1] = { 'a','b',...};具体数字忘了,可以查一下;
for(i=0;!(*pCur);i++)
if(*pCur++ != uAscii[i]) //不是英文字母
continue;
......
汉字的内码不在表里,所以找到的都是英文字幕.
yokel 2003-08-08
  • 打赏
  • 举报
回复
To tigerfox(风之力:=初级程序员.奋斗.被开发中)
我修改了一下,否则
会把"@!d"这样的东西认为是单词
还欠10分,近期开帖奉上,到时通知你
yokel 2003-08-08
  • 打赏
  • 举报
回复
好用,又学了几招
skink 2003-08-06
  • 打赏
  • 举报
回复
mark
yokel 2003-08-06
  • 打赏
  • 举报
回复
高手赐教啊,
不知道的麻烦up一下,肯定给分
yokel 2003-08-05
  • 打赏
  • 举报
回复
其实我想做的4,
等待中....
xiaohedou 2003-08-05
  • 打赏
  • 举报
回复
网友的文章:非本人作
关于CString总结

前言:串操作是编程中最常用也最基本的操作之一. 做为VC程序员,无论是菜鸟或高手都曾用过CString.而且好像实际编程中很难离得开它(虽然它不是标准C++中的库).因为MFC中提供的这个类对我们操作字串实在太方便了,CString不仅提供各种丰富的操作函数、操作符重载,使我们使用起串起来更象basic中那样直观;而且它还提供了动态内存分配,使我们减少了多少字符串数组越界的隐患。但是,我们在使用过程中也体会到CString简直太容易出错了,而且有的不可捉摸。所以有许多高人站过来,建议抛弃它。

在此,我个人认为:CString封装得确实很完美,它有许多优点,如“容易使用 ,功能强,动态分配内存,大量进行拷贝时它很能节省内存资源并且执行效率高,与标准C完全兼容,同时支持多字节与宽字节,由于有异常机制所以使用它安全方便” 其实,使用过程中之所以容易出错,那是因为我们对它了解得还不够,特别是它的实现机制。因为我们中的大多数人,在工作中并不爱那么深入地去看关于它的文档,何况它还是英文的。

由于前几天我在工作中遇到了一个本不是问题但却特别棘手、特别难解决而且莫名惊诧的问题。最后发现是由于CString引发的,后来,没办法,我把整个CString的实现全部看了一遍,才慌然大悟,并彻底弄清了问题的原因(这个问题,我已在csdn上开贴)。在此,我想把我的一些关于CString的知识总结一番,以供他(她)人借鉴,也许其中有我理解上的错误,望发现者能通知我,不胜感谢。



1 CString实现的机制.

CString是通过“引用”来管理串的,“引用”这个词我相信大家并不陌生,象Window内核对象、COM对象等都是通过引用来实现的。而CString也是通过这样的机制来管理分配的内存块。实际上CString对象只有一个指针成员变量,所以任何CString实例的长度只有4字节.

即: int len = sizeof(CString);//len等于4

这个指针指向一个相关的引用内存块,如图: CString str("abcd");

___

____________ | |

| | | |

| 0x04040404 | | | head部,为引用内存块相关信息

|____________| | |

str |___|

|'a'| 0x40404040

|'b'|

|'c'|

|'d'|

| 0 |



正因为如此,一个这样的内存块可被多个CString所引用,例如下列代码:

CString str("abcd");

CString a = str;

CString b(str);

CString c;

c = b;

上面代码的结果是:上面四个对象(str,a,b,c)中的成员变量指针有相同的值,都为0x40404040.而这块内存块怎么知道有多少个CString引用它呢?同样,它也会记录一些信息。如被引用数,串长度,分配内存长度。

这块引用内存块的结构定义如下:

struct CStringData

{

long nRefs; //表示有多少个CString 引用它. 4

int nDataLength; //串实际长度. 4

int nAllocLength; //总共分配的内存长度(不计这头部的12字节). 4

};

由于有了这些信息,CString就能正确地分配、管理、释放引用内存块。

如果你想在调试程序的时候获得这些信息。可以在Watch窗口键入下列表达式:

(CStringData*)((CStringData*)(this->m_pchData)-1)或

(CStringData*)((CStringData*)(str.m_pchData)-1)//str为指CString实例



正因为采用了这样的好机制,使得CString在大量拷贝时,不仅效率高,而且分配内存少。





2 LPCTSTR 与 GetBuffer(int nMinBufLength)

这两个函数提供了与标准C的兼容转换。在实际中使用频率很高,但却是最容易出错的地方。这两个函数实际上返回的都是指针,但它们有何区别呢?以及调用它们后,幕后是做了怎样的处理过程呢?

(1) LPCTSTR 它的执行过程其实很简单,只是返回引用内存块的串地址。 它是作为操作符重载提供的,

所以在代码中有时可以隐式转换,而有时却需强制转制。如:

CString str;

const char* p = (LPCTSTR)str;

//假设有这样的一个函数,Test(const char* p); 你就可以这样调用

Test(str);//这里会隐式转换为LPCTSTR

(2) GetBuffer(int nMinBufLength) 它类似,也会返回一个指针,不过它有点差别,返回的是LPTSTR

(3) 这两者到底有何不同呢?我想告诉大家,其本质上完全不一样,一般说LPCTSTR转换后只应该当常量使用,或者做函数的入参;而GetBuffer(...)取出指针后,可以通过这个指针来修改里面的内容,或者做函数的入参。为什么呢?也许经常有这样的代码:

CString str("abcd");

char* p = (char*)(const char*)str;

p[2] = 'z';

其实,也许有这样的代码后,你的程序并没有错,而且程序也运行得挺好。但它却是非常危险的。再看

CString str("abcd");

CString test = str;

....

char* p = (char*)(const char*)str;

p[2] = 'z';

strcpy(p, "akfjaksjfakfakfakj");//这下完蛋了

你知道此时,test中的值是多少吗?答案是"abzd".它也跟着改变了,这不是你所期望发生的。但为什么会这样呢?你稍微想想就会明白,前面说过,因为CString是指向引用块的,str与test指向同一块地方,当你p[2]='z'后,当然test也会随着改变。所以用它做LPCTSTR做转换后,你只能去读这块数据,千万别去改变它的内容。



假如我想直接通过指针去修改数据的话,那怎样办呢?就是用GetBuffer(...).看下述代码:

CString str("abcd");

CString test = str;

....

char* p = str.GetBuffer(20);

p[2] = 'z'; // 执行到此,现在test中值却仍是"abcd"

strcpy(p, "akfjaksjfakfakfakj"); // 执行到此,现在test中值还是"abcd"

为什么会这样?其实GetBuffer(20)调用时,它实际上另外建立了一块新内块存,并分配20字节长度的buffer,而原来的内存块引用计数也相应减1. 所以执行代码后str与test是指向了两块不同的地方,所以相安无事。

(4) 不过这里还有一点注意事项:就是str.GetBuffer(20)后,str的分配长度为20,即指针p它所指向的buffer只有20字节长,给它赋值时,切不可超过,否则灾难离你不远了;如果指定长度小于原来串长度,如GetBuffer(1),实际上它会分配4个字节长度(即原来串长度);另外,当调用GetBuffer(...)后并改变其内容,一定要记得调用ReleaseBuffer(),这个函数会根据串内容来更新引用内存块的头部信息。

(5) 最后还有一注意事项,看下述代码:

char* p = NULL;

const char* q = NULL;

{

CString str = "abcd";

q = (LPCTSTR)str;

p = str.GetBuffer(20);

AfxMessageBox(q);// 合法的

strcpy(p, "this is test");//合法的,

}

AfxMessageBox(q);// 非法的,可能完蛋

strcpy(p, "this is test");//非法的,可能完蛋

这里要说的就是,当返回这些指针后, 如果CString对象生命结束,这些指针也相应无效。



DDHuang 2003-08-05
  • 打赏
  • 举报
回复
在建立console程序时app wizard里mfc support那个地方打钩
切换倒用不着,在字符串前加 L就表示该字符串做 unicode处理
TCHAR *szabc=L"abc";
hellwolf 2003-08-05
  • 打赏
  • 举报
回复
既然是在console下,不如直接用std::string

实在要用,#include <afxwin.h>
xiaohedou 2003-08-05
  • 打赏
  • 举报
回复
前两天又人总结过,待会贴给你:

2。CString就很好
3。应该是“按”内码的第一个字节;
4。char mychSet[27]={'a','b'...'z','\0'};
char *pSet = mychSet;
char *pCur="Hello,....";
while(pCur) {
while(pSet)
if(*pCur == *pSet++ ) { do something... };
pCur++;
}

yokel 2003-08-05
  • 打赏
  • 举报
回复
而"按时的"是汉字",它占两字字节,——这个道理我是懂的
关键是怎样作到象VB一样的效果
yokel 2003-08-05
  • 打赏
  • 举报
回复
To lygfqy(风清扬) :
我是在控制台程序中用,不行吗?如何加入MFC支持呀。

To wangjinwang(王进)
如何切换到unicode编程模式?

zhucde 2003-08-05
  • 打赏
  • 举报
回复
CString 是直接可以用的,该类在AFX.h中定义,MFC程序肯定已经包含进来.
对于char cl[]="9z按时的sdf";
它不是像你想的那样,9,z都是一个字节,8位,而"按时的"是汉字",它占两字字节,
所以cl[0]是9,cl[1]是z,但cl[2]却不是按,应该是cl[2]和cl[3]结合起来才是"按"
canoe_eyes 2003-08-05
  • 打赏
  • 举报
回复
cstring 直接可以使用在MFC,它其中的成员函数可以很方便的搞定。
lygfqy 2003-08-05
  • 打赏
  • 举报
回复
更正:按字应该为cl[2]和cl[3],汉字在非unicode的情况下占两个
孤必有邻 2003-08-05
  • 打赏
  • 举报
回复
1 CString在Afx.h中,通常不需要你直接引用,其它常规头文件里有引用
2 也就CString
3 用unicode编程模式可以取得“按”的偏移值为3,要取得2,只能自己扫描判断
4 用unicode编程模式:字符是1,汉字也是1
lygfqy 2003-08-05
  • 打赏
  • 举报
回复
在mfc下,cstring可以直接用,不需要什么头文件阿,照你的定义,cl[2]就是按字,字符串的偏移就是字符的个数阿
yokel 2003-08-05
  • 打赏
  • 举报
回复
汉字的问题没法解决!!
yokel 2003-08-05
  • 打赏
  • 举报
回复
我试试,大家也帮我试试
分有的是
加载更多回复(2)

16,471

社区成员

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

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

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