zoukankan      html  css  js  c++  java
  • strcpy和strncpy

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

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

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

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

    strcpy的函数原型:

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

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

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

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

    比如:

    char* dst;
    strcpy(dst,src);

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

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

    比如:

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

    结果为:

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

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

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

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

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

    比如:

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

    输出结果为:

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

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

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

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

  • 相关阅读:
    职业生涯系列
    自我进修系列
    每周问题系列
    职业生涯系列
    软件测试专用名词
    Java系列 – 用Java8新特性进行Java开发太爽了(续)
    Java系列
    EJB系列
    EJB系列
    EJB系列
  • 原文地址:https://www.cnblogs.com/qingergege/p/5969571.html
Copyright © 2011-2022 走看看