首页 > 教育培训

为什么要用strcpy给字符串赋值 C语言中怎么字符串赋值?

c语言中怎么字符串赋值?

需要准备的材料有:计算机和c语言编译器。

1.首先,打开c语言编译器并创建一个初始。cpp文件,例如test.cpp。

2.在test.cpp文件中,输入c语言代码:chara[20]strcpy(a,

为什么要用strcpy给字符串赋值 C语言中怎么字符串赋值?

strcpy是什么意思?

c语言的标准库函数strcpy,将从src地址开始并包含空终止符的字符串复制到从dest开始的地址空间。直观表示为strcpy(dog,赋值内容),实现了字变量dog的赋值,区别于普通数字。原型声明:externchar*strcpy(char*dest,constchar*src);头文件:#includ

strcpy函数怎么用?

首先,使用步骤如下

1.头文件:#includeltstring.hgt和#includelstdio.hgt。

2.功能:将从src地址开始并包含空终止符的字符串复制到从dest开始的地址空间。

3.描述:src和dest指示的内存区域不能重叠,dest必须有足够的空间来容纳src字符串。返回一个指向目标的指针。

第二,拓展

//c语言标准库函数strcpy的典型工业最简单实现。

//返回值:目标字符串的地址。

//参数:des是目标字符串,source是原始字符串。

char*strcpy(char*des,constchar*source){

char*rdes

断言((des!null)ampamp(来源!null))

while((*r*source)!#390#39)

返回des

}

//while((*des*source))的解释:赋值表达式返回左操作数,所以在赋值#390#39之后,循环停止。

例如:

chara[10],b[]{#34copy#34}

//定义字符数组a,b

strcpy(a,b)

//将副本从b复制到a。

strcpy函数中的缓冲区溢出及其防范

c语言和c语言以其轻松灵活的风格和宽松的语法限制,受到各类程序员的欢迎。它们是比较常见的编程语言,也是各大高校计算机专业的基础语言课程。strcpy函数由于不检查数组边界,非常容易造成各种缓冲区溢出漏洞。这些漏洞很容易被利用,导致严重的系统问题。使用strcpy函数,要小心。strcpy函数中的缓冲区溢出及其预防措施将在下面讨论。[1]

缓冲区溢出问题

缓冲区溢出是指程序在动态分配的缓冲区中写入了过多的数据,使得分配的区域溢出。一旦一个缓冲区可以通过使用程序把运行指令放到root权限的内存中,并运行这些指令,就可以用root权限控制计算机了。[1]

strcpy函数的安全编码

编程时,通过增加错误检查,可以及时发现错误,处理出现的异常。写strcpy函数时,先把目的缓冲区的长度做得尽可能长,然后检查目的缓冲区和源缓冲区。如果目标缓冲区或源缓冲区为空,程序将在异常处理中结束。如果源字符串不长于目标缓冲区,还应该在异常处理中结束程序,以防止溢出。任何程序都很难说是绝对安全的,strcpy函数只能以最安全的处理。只要输入字符串不以空字符结尾,该函数将随时终止。这种检测很容易实现。然而,这种检测并不能确保该功能一定是安全的。[1]

另外,每增加一个错误检查,都会让程序更加复杂,可能会产生很多bug,增加很多工作量。最重要的是,即使程序设计得非常仔细,也可能会忽略一些细节,导致不可挽回的错误。所以写程序的时候,最保险的办法就是尽量不要用strcpy函数。可以在程序开头添加#definestrcpyunsafe_strcpy。这样strcpy函数在编译时就会产生错误,这样我们在编程时就可以完全抛弃strcpy函数了。当strcpy函数被完全抛弃后,很多依附于strcpy函数的bug也被抛弃。[1]

特殊情况描述

已知strcpy函数的原型是:

char*strcpy(char*strdest,constchar*strsrc)

1.不调用库函数实现strcpy函数。

2.解释为什么要返回char*。

不调用库函数如何实现strcpy函数

strcpy的实现代码

char*strcpy(char*strdest,constchar*strsrc){

if((nullstrdest)||(nullstrrc))

//[1]

抛出#34无效参数#34

//[2]

char*strdestcopystrdest

//[3]

瓦特小时ile((*strdest*strsrc)!#390#39)

//[4]

返回strdestcopy

}

错误做法[1]:

(a)不检查指针的有效性意味着回答者不注意代码的健壮性。

使用((!strdest)||(!strsrc))或(!(strdestampampstrsrc)),说明回答者对c语言中类型的隐式转换没有深刻的理解。在这种情况下,从char*到bool的转换是隐式类型转换。这个功能虽然灵活,但是会导致出错概率更大,维护成本更高。所以c特别添加了bool,true和false关键字,提供了一个更安全的条件表达式。

(c)在检查指针的有效性时使用((strdest0)||(strrc0)),表示回答者不知道使用常数的好处。直接使用文字常量(比如本例中的0)会降低程序的可维护性。虽然0很简单,但是程序中可能会有很多对指针的检查。万一出现笔误,编译器可以t找不到,生成的程序包含逻辑错误,很难消除。用null代替0,如果有拼写错误,编译器会检查出来。

错误的[2]:

(a)返回新字符串(#34无效参数#34);说明回答者对返回值的用途没有概念,对内存泄漏没有警觉。从函数中返回分配在函数体中的内存是非常危险的。他把释放记忆的义务扔给了毫无戒心的呼叫者。在大多数情况下,调用者不会释放内存,从而导致内存泄漏。

(b)返回0;,说明回答者没有掌握异常机制。调用者可能忘记检查返回值,调用者可能无法检查返回值(见下面的链式表达式)。如果想让返回值肩负起返回正确值和异常值的双重功能,结果往往是两个功能都无效。返回值应该用抛出异常来代替,这样可以减轻调用者的负担,使错误不被忽略,增强程序的可维护性。

错误的[3]:

(一)忘记保存原始strdest值,说明回答者逻辑思维不严谨。

错误的[4]:

(a)将循环写成while(*strtestcopy*strsrc);,同[1](b)。

(b)循环被写成while(*strrc!#390#39)*strdest*strsrc;,表明被告对边界条件的检查是薄弱的。在循环体结束后,strdest字符串的末尾没有正确添加#390#39。

解释为什么要返回char*

返回strdest的原始值以生成函数它可以支持链表达式并增加"附加值和利润的功能。功能相同的功能,如果可用性能得到合理提升,自然更理想。

链表达式的形式如下:

intilengthstrlen(strcpy(stra,strb))

另一个例子是:

char*strastrcpy(新char[10],strb)

返回strsrc的原始值是错误的。第一,源字符串必须是已知的,返回没有意义。第二,不能支持第二个例子那样的表达式。第三,为了保护源字符串,形参使用const限制strsrc引用的内容,返回constchar*作为char*。类型不匹配,编译器报告错误。

在上面的语句中,循环语句

while((*strdestcopy*strsrc)!#390#39)

很难理解,这句话可以理解为下面的操作。

第一种:

while(1){

炭化温度

*strdestcopy*strsrc

温度*strsrc

strdestcopy

strsrc

如果(#390#39温度)

破裂

}

第二种类型:

while(*strrc!#390#39){

*strdestcopy*strsrc

strdestcopy

strsrc

}

*strdestcopy*strsrc

即:

while(*strrc!#390#39){

*strdestcopy*strsrc

}

*strdestcopy“0”

使用示例

//例1:将一个字符串复制到一个足够长的字符数组中。在本例中,字符数组是一个,长度为20。

//缺点:如果数组长度不足以容纳整个字符串,程序会崩溃。

#includeltiostreamgt

#includeltstdlib.hgt

使用命名空间标准

char*strcpy(char*strdest,constchar*strsrc){

char*strdestcopystrdest

if((nullstrdest)||(nullstrrc))抛出#34无效参数#34

while((*strdest*strsrc)!#390#39)

返回strdestcopy

}

intmain(intargc,char*argv[]){

chara[20],c[]#34我是老师!#34

尝试{

strcpy(a,c)

}catch(char*strinfo){

coutltltstrinfoltltendl

退出(-1)

}

coutltltaltltendl

返回0

}

//例2:预置了两个字符指针,一个指向字符串,一个指向null,在程序运行过程中复制。

#includeltiostreamgt

使用命名空间标准

char*strcpy(char*strdes,constchar*strsrc)

//函数声明

intmain(){

constchar*strrc#34helloworld#34

char*strdesnull

strdesstrcpy(strdes,strsrc)

coutltlt#34strsrc#34ltlstrsrcltltendl

coultlt#34strdes#34ltltstrdestltendl

如果(strdes!null){

免费(strdes)

strdesnull

}

返回0

}

char*strcpy(char*strdes,constchar*strsrc){

断言(strsrc!空)

//如果strsrc为null,则引发异常。

strdes(char*)malloc(strlen(strsrc)1)

//多一个空间用于存储字符串终止符#390#39。

char*pstrdes

while(*strrc!#390#39){

*p*strsrc

}

*p#390#39

返回strdes

}

还有一个模拟算法:

char*strcpy(char*dest,constchar*src){

char*pdest

while(*src!#390#39){

*dest*src

目标服务中心

}

*目的地#390#39

返回p

}

与strncpy的区别

第一种情况:

你好吗?#34

字符ame[20]34abcdefghijklmnopqrs#34

strcpy(名称,p)

//名字改成#34你好吗?#34gt正确!

strncpy(name,p,sizeof(name))

//名字改成#34你好吗?#34gt正确!后续字符将为空。

第二种情况:

你好吗?#34

字符名称[10]

strcpy(名称,p)

//目标字符串的长度小于源字符串的长度,错误!

名称[sizeof(name)-1]

//和上一步结合起来弥补结果,但这是不可取的,因为上一步的错误处理方法是不确定的。

strncpy(name,p,sizeof(name))

//源字符串的长度大于指定副本sizeof(name)的长度。请注意,在这种情况下,#390#39不会自动添加到目标字符串之后。

名称[sizeof(name)-1]

字符串函数strcpy程序

原文标题:为什么要用strcpy给字符串赋值 C语言中怎么字符串赋值?,如若转载,请注明出处:https://www.xinyige.net/tag/26928.html
免责声明:此资讯系转载自合作媒体或互联网其它网站,「鑫艺阁」登载此文出于传递更多信息之目的,并不意味着赞同其观点或证实其描述,文章内容仅供参考。