在c语言中,对于简单变量,如int型、double型,直接使用赋值符号“=”,即可完成赋值,如

int a=10;

int b;

b=a;

即可完成用a给b赋值。

但是对于字符串,这样赋值是不准确的。

比如:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char src[]; printf("enter:\n");
if( fgets(src,,stdin))
{
//如果输入的有效字符少于9个,则说明src中存在'\n',这时去掉'\n'
//如果输入的有效字符大于9个,则缓冲区中会残余字符,这时用getchar()函数吸收掉
int i=;
while(src[i] !='\0' && src[i] !='\n')
i++;
if(src[i]=='\n')
src[i]='\0';
else
while(getchar() != '\n')
continue; }
char* dst;
dst=src;
printf("-----------------------------------\n");
puts(dst); src[]='z';
printf("-----------------------------------\n");
puts(dst);
return ;
}

我们发现当用赋值语句dst=src给dst赋值后,如果改变字符串src的值,dst的值也会随之改变,而对于简单变量则不会出现这种情况。

这时因为 dst=src,仅仅是地址之间的赋值。

要想对字符串进行赋值需要使用strcpy()函数,这个函数就相当于简单变量的赋值符号"=";

strcpy的函数原型:

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

作用:把从src地址开始且含有'\0'结束符的字符串复制到以dest开始的地址空间。

这里需要注意的是:第一个参数应该指向一个数据对象(如数组),且该对象有足够的存储空间用于存储源字符串,第二个参数可以是指向数组的指针、数组名或者字符串常量。

首先:dest应该是一片内存的首地址,不能是没有分配内存的指针。

比如:

char* dst;
strcpy(dst,src);

这里dst没有分配内存空间,运行时会出错

再者:dest 所指向的内存空间一定要足够存储源字符串。

比如:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char* src="中国人们解放军,中华人民共和国,中央人民政府,中共中央,总书记,呵呵哒"; char dst[];
strcpy(dst,src);
printf("-----------------------------------\n");
puts(dst);
return ;
}

结果为:

可以看到:虽然能够完整输出,但是程序会异常中断。其实有可能也会正常输出,但这种正常是不可靠的,因为很显然dst的大小为2,而源字符串的长度要大于2,这必然造成程序访问未知的内存空间,给程序带来不确定性。

strncpy 相对于strcpy函数多了一个表示可拷贝的最大字符数的参数。这样在很大程度上就能避免strcpy函数的不足(程序员在用strncpy时,需要填写拷贝个数,这时程序员就很肯能会检查一下dest是否有足够的内存)。

原型:char *strncpy(char *dest, const char *src, int n);

要注意:n表示可拷贝的最大字符数,如果提前遇到'\0',拷贝的长度会小于n.

另外,如果仅拷贝源字符串的一部分,可能会造成目标串没有字符串结束标志'\0';

比如:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char* src="abcdefghijklmnopq"; char dst[];
strncpy(dst,src,);
printf("-----------------------------------\n");
puts(dst);
return ;
}

输出结果为:

可以看到有乱码输出,这就是因为拷贝的只是源字符串的一部分,abcd ,这其中并没有字符串结束标志'\0';因此dst中也就没有字符串结束标志'\0',所以会输出乱码,。

为解决这一问题可以做如下修改:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char* src="abcdefghijklmnopq"; char dst[];
strncpy(dst,src,-);
dst[-]='\0';
printf("-----------------------------------\n");
puts(dst);
return ;
}

拷贝n-1个字符,最后在字符串结尾手动添加'\0'结束标志,这样做比较安全。

strcpy和strncpy的更多相关文章

  1. strcpy、strncpy与memcpy的区别与使用方法

    strcpy.strncpy.memcpy这三个C语言函数我们在主机代码编写中会很频繁的使用到,但是三个函数的区别.使用时该注意什么还是有必要说下的. 本文参考<C 标准库>编写. 一.函 ...

  2. strcpy、strncpy、memcpy的区别

    一.strcpy.strncpy区别 struct gpInfo { char gpcode[9]; char gpName[50]; }; string gpstr = "SZ000001 ...

  3. [置顶] strcpy()与strncpy()的区别

    头文件:#include <string.h> strcpy() 函数用来复制字符串,其原型为: char *strcpy(char *dest, const char *src); [参 ...

  4. C语言 - strcpy和strncpy的编程实现及总结

    一.字符串的strcpy与strncpy函数 1.编程实现strcpy函数(笔试很容易考到) 要求: 原型:char *stpcpy(char *strDest,char *strSrc); 头文件: ...

  5. c常用函数-strcpy和strncpy

    strcpy和strncpy strcpy在脚本开发中经常用到,例如处理参数等,它的作用是把一个字符串复制到另一个字符串中. strncpy的作用是把一个字符串中的指定长度复制到另一个字符串中,如果指 ...

  6. strcpy、strncpy 和安全的strncpy_s

    strcpy和strncpy摘于linux 内核源码的/lib/string.c char *self_strcpy(char *dest, const char *src) { char *tmp ...

  7. Linux C 字符串函数 strlen()、strcat()、strncat()、strcmp()、strncmp()、strcpy()、strncpy() 详解

      strlen(返回字符串长度) 表头文件 #include <string.h> 定义函数 size_t strlen(const char *s); 函数说明 strlen()用来计 ...

  8. C++ strcpy strcpy_s strncpy strlcpy

    strncpy的用法:它与strcpy的不同之处就在于复制n个字符,而不是把所有字符拷贝(包括结尾'\0'). 函数原型:char * strncpy(char *dst,const char * s ...

  9. c语言中几个常见的库函数strlen、strcmp、strcat、strcpy、strncpy、memset、memcpy、memmove、mmap

    1.strlen() 1)计算给定字符串的长度,不包括’\0’在内 unsigned int strlen(const char *s) { assert(NULL != s);//如果条件不满足,则 ...

随机推荐

  1. [C#]获取当前程序运行路径的方法集合(转)

    //获取当前进程的完整路径,包含文件名(进程名).string str = this.GetType().Assembly.Location;result: X:\xxx\xxx\xxx.exe (. ...

  2. spark-streming 中调用spark-sql时过程遇到的问题

    在spark-streming 中调用spark-sql时过程遇到的问题 使用版本:spark-2.1.0 JDK1.8 1. spark-sql中对limit 的查询结果使用sum() 聚合操作不生 ...

  3. Wpf Page间跳转传参数 And Window To Page

    这段时间用到Wpf,页面间的跳转网上有不少的示例,但是有些已经不能用了,尤其是页面间的传参问题更是一大堆,但正确的解决方案却没有几个,或者说写的不清楚,让人走了很多弯路,查看官方文档后发现了正确的姿势 ...

  4. MD5签名

    /// <summary>        /// 校验签名        /// </summary>        /// <param name="mode ...

  5. java—在dbutils中处理事务与不确定条件的查询(46)

    在dbutils中处理事务        事务是指用户的一次操作.这一次操作有可能是一个表,也有可能是多个表,也有可能是对一个表的多次操作. 只要是: 1:对数据数据库进行多次操作. 2:多个表,还是 ...

  6. 深入了解java虚拟机(JVM) 第七章 内存分配策略

    理解了jvm内存分配策略不仅是程序性能调优的重要知识,还能够给养成自己一种良好的代码思路,一个程序的代码差异往往都是在这里体现出来的. 一.对象优先分配到Eden区域   一般来说,新创建的对象都会直 ...

  7. css3动画水波纹、波浪

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. django rest framework实现分页功能

    在web开发中很多需求都需要实现分页功能,然而 Django Rest Framework 自带的分页功能,只能在 mixins.ListModelMixin and generics.Generic ...

  9. 深入理解Scala的隐式转换

    摘要: 通过隐式转换,程序员可以在编写Scala程序时故意漏掉一些信息,让编译器去尝试在编译期间自动推导出这些信息来,这种特性可以极大的减少代码量,忽略那些冗长,过于细节的代码.   使用方式: 1. ...

  10. django 运行报错汇总

    记录自己在使用django开发过程中遇到的问题,不间断更新. (1) 独立运行普通Python脚本调用django中定义的类报错 报错信息: django.core.exceptions.Improp ...