String和内存操作

来源:互联网 发布:学霸是怎样炼成的 知乎 编辑:程序博客网 时间:2024/06/07 12:36

String和内存操作

分类: C++再学习系列 2009-09-15 16:42707人阅读 评论(2)收藏 举报
stringbufferstructcrash存储c

C99有很多和string相关的函数,如strcat,strchr,strcmp,strcpy,strlen,strncat,strncmp,strncpy等。然而使用C++编程时,所有和string相关的操作均可以使用string类的相关接口完成,string提供和原来C接口类似的功能和性能,同时提供更高的安全性。

String类有一个特性:a string of length n must manage a block ofmemory whose size is at least n + 1。即长度为nstring对象,其内存空间至少为n+1个字符,且最后一个字符为’/0’

不过在进行string操作时,有一点必须牢记:C/C++语言的string是以’/0’结尾的,对不以’/0’结尾的string进行操作容易引发错误,甚至导致内存溢出等crash

C++的string类,除了用于处理常规string操作外,其本身也可用于存储各种数据,如文件数据,此时并不要求string对象必须以’/0’结尾。使用者采用string( const char* str, size_type length ); 来封装特定长度的char*数据块。String类的各种运算符将保证数据传递的完整性,即string对象。

示例:

#include<iostream>

using namespacestd;

int main()

{

        std::string str("teststring");

        cout<<str<<"  "<<str.c_str()<<endl;

        cout<<str.size()<<endl;

 

        char* buf = new char[str.size()+1];

        memset(buf, 0, sizeof(buf));

 

        string test(buf, str.size());   //封装非字符数据

        cout<<test<<"  "<<test.c_str()<<endl;

        cout<<test.size()<<endl;

 

        memcpy(buf, str.c_str(), str.size());

 

        test = string(buf, str.size());  //封装字符数据,并自动加上’/0’结束符

        cout<<test<<"  "<<test.c_str()<<endl;

        cout<<test.size()<<endl;

 

        return 0;

}

其输出:

teststring  test string

11

 

11

teststring  test string

11

 

说明:这个例子说明:当使用string( const char* str, size_type length );来构造string对象时,string对象的长度由外部指定,数据则来自str,如果length大于str地址范围,可能引发crash!

这个例子也说明了string可用于封装数据,即使是’/0’的数据。因此,string类可以用于存储各种数据,字符串、非字符串(图片、视频)等数据。

注意:将数据拷贝到内存时,不要使用strcpy,应该使用memcpy,因为strcpystrncpy碰到’/0’将认为拷贝结束。总之,不要使用和str***相关的函数去操作内存数据,除非数据只能是string(memcpy完全可拷贝任何数据)。

 

附录:

内存初始化函数memset()

作用:在一段内存中填充某个给定的值,注意填充时是按照字节顺序填充的,而不是按照元素填充。

此方法是对较大的结构体和数组进行清零操作的一种有效方法。一般用于初始化大块的内存,此时memset远比for循环高效。

函数形式:memset(void *buffer, int c, size_t n)

buffer是需要设置的内存的开始地址;c是期望填充值;n是需要填充的字节数。

例1:一个int

a[10]型变量,则memset(a,100,sizeof(int))此操作后,元素a[0]的每个字节的值都是100,即0x64,二进制表示:

01100100,所以元素a[0]为0x64646464,二进制表示:01100100 01100100 0110010001100100

void main()

{ int i,a[20];

memset(a,10,5*sizeof(int));

for(i=0;i<20;i++)

cout< 此函数输出的10个元素并非10,而是每个字节都是00001010组成的int型数。

例2:

#include

#include

void main( void)

{

char buffer[] ="This is a test of the memset function";

printf("Before: %s/n", buffer );

memset( buffer,'*', 4 );

printf("After: %s/n", buffer );

}

Output

Before: This isa test of the memset function

After: **** isa test of the memset function

 

Memset用来对一段内存空间全部设置为某个字符,一般用在对定义的字符串进行初始化为''或'/0';

例:char a[100];

memset(a, '/0',sizeof(a));

 

memset可以方便地清空一个结构体类型的变量或数组。

如:

structsample_struct

{

charcsName[16];

int iSeq;

int iType;

};

对于变量

structsample_strcut stTest;

一般情况下,清空stTest的方法:

stTest.csName[0]='/0';

stTest.iSeq=0;

stTest.iType=0;

用memset就非常方便:

memset(&stTest,0,sizeof(structsample_struct));

如果是数组:

structsample_struct TEST[10];

则memset(TEST,0,sizeof(struct sample_struct)*10);

 

Memcpystrcpy

原型:

void *memcpy(void *to, const void *from, size_t count );

char *strcpy(char *dest, const char *src );

memcpy 用来做内存拷贝,可拷贝任何数据类型的数据或对象。

例:char a[100],b[50]; memcpy(b, a, sizeof(b));

注意如果用memcpy(b,a,sizeof(a)),很可能会造成b的内存地址溢出。

 

Strcpy就只能拷贝字符串,它遇到'/0'就结束拷贝。

例:char a[100],b[50];strcpy(a,b);如用strcpy(b,a),要注意a中的字符串长度(第一个‘/0’之前)是否超过50位,如超过,则会造成b的内存地址溢出。

Strcpy有可指定拷贝个数的版本:char *strncpy( char *to,const char *from, size_t count );

总结:

strcpy

  源字串全部拷贝到目标字串中,包括'/0',但是程序员必须保证目标串长度足够,且不与源串重叠。

strncpy

  如果目标长>=指定长>源长,则将源串全部拷贝到目标串,连同'/0'

  如果指定长<源长,则将截取源串中按指定长度拷贝到目标字符串,不包括'/0'

  如果指定长>目标长,错误!

 

注意:说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。对于memcpy也是同样的限制。如果拷贝区域有重叠,请使用memmove().

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 直肠上长了瘤怎么办 上嘴唇没有唇峰怎么办 拉屎厕所堵了怎么办啊 小孩一拉屎就哭怎么办 上火裆部有肿块特别疼怎么办 狗狗拉屎拉不出来怎么办 肛裂大便带血怎么办 辣椒不小心弄丁丁上怎么办 小鸡躺着不动还呼吸怎么办 老人身体不舒服不敢去检查怎么办 金毛上火鼻子干怎么办 狗鼻子干裂结壳怎么办 小狗吐了没精神怎么办 狗狗又吐又拉怎么办 孕妇嘴干鼻子干怎么办 狗狗打了针皮肤变硬怎么办 狗狗得了狗瘟怎么办 金毛得了犬瘟怎么办 泰迪身上起皮怎么办 狗狗鼻子干了怎么办 泰迪生病鼻子干怎么办 痔疮手术后肛门狭窄怎么办 乳腺导管扩张奶头疼怎么办 3月的宝宝要扩肛才拉便便怎么办 怀孕期间肛门长痔疮怎么办 射精后检查尿液发现蛋白尿怎么办 铁距孔被小孩拿体温计塞了怎么办 肛门长了个息肉怎么办 不小心吃了虫卵怎么办 孕妇做四维宝宝不配合怎么办 孕妇四维小孩不配合怎么办 孕妇吃了甜酒酿怎么办 屁股疼的不能动怎么办 小孩打针后手臂疼痛怎么办 屁股打针的地方疼怎么办 眼底坏了怎么办怎么治 大疆无人机飞丢了怎么办 两岁半宝宝发热灌肠后便秘怎么办 发烧灌肠后一直拉稀怎么办 孩子便秘用开塞露引起肚子疼怎么办 老人大便干燥拉不出来怎么办