• C++ strcpy strcpy_s strncpy strlcpy


    strncpy的用法:它与strcpy的不同之处就在于复制n个字符,而不是把所有字符拷贝(包括结尾'')。
    函数原型:char * strncpy(char *dst,const char * src, int n)
      当src的长度小于n时,dst内的未复制空间用''填充。否则,复制n个字符到dst,没有加''。这里就要注意在字符串dst结尾处理加''的情况了
    strcpy ,strncpy ,strlcpy的用法好多人已经知道利用strncpy替代strcpy来防止缓冲区越界。
    但是如果还要考虑运行效率的话,也许strlcpy是一个更好的方式。


    1. strcpy
    我们知道,strcpy 是依据 作为结束判断的,会自动在缓冲区的string后加,如果 to 的空间不够,则会引起 buffer overflow。strcpy 常规的实现代码如下(来自 OpenBSD 3.9):

    char *strcpy(char *to, const char *from)
    {
           char *save = to;
           for (; (*to = *from) != ''; ++from, ++to);
           return(save);
    }
    但通常,我们的 from 都来源于用户的输入,很可能是非常大的一个字符串,因此 strcpy 不够安全。

    2. strcyp_s

    它和strcpy()函数的功能应该一样的。strcpy函数,就象gets函数一样,它没有方法来保证有效的缓冲区尺寸,所以它只能假定缓冲足够大来容纳要拷贝的字符串。在程序运行时,这将导致不可预料的行为。用strcpy_s就可以避免这些不可预料的行为。

    这个函数用两个参数、三个参数都可以,只要可以保证缓冲区大小。
    三个参数时:
    errno_t strcpy_s( 
    char *strDestination, 
    size_t numberOfElements, 
    const char *strSource 
    );
    两个参数时:
    errno_t strcpy_s( 
    char (&strDestination)[size], 
    const char *strSource 
    ); // C++ only 

    需要注意的是如果需要使用两个参数的版本,则strDestination所指向的空间必须时静态分配的,而不能是动态new出出来的堆内存。


    3. strncpy
    在 ANSI C 中,strcpy 的安全版本是 strncpy。
    char *strncpy(char *s1, const char *s2, size_t n);
    但 strncpy 其行为是很诡异的(不符合我们的通常习惯)。标准规定 n 并不是 sizeof(s1),而是要复制的 char 的个数。一个最常见的问题,就是 strncpy 并不帮你保证 结束。
    char buf[8];
    strncpy( buf, "abcdefgh", 8 );
    看这个程序,buf 将会被 "abcdefgh" 填满,但却没有 结束符了。
    另外,如果 s2 的内容比较少,而 n 又比较大的话,strncpy 将会把之间的空间都用 填充。这又出现了一个效率上的问题,如下:
    char buf[80];
    strncpy( buf, "abcdefgh", 79 );
    上面的 strncpy 会填写 79 个 char,而不仅仅是 "abcdefgh" 本身。

    strncpy 的标准用法为:(手工写上 )
    strncpy(path, src, sizeof(path) - 1);
    path[sizeof(path) - 1] = '';
    len = strlen(path);

    4. strlcpy
    复制src到大小为siz目的缓冲区,最多复制siz-1个,第siz个位置会被添加'',执行结束后会返回 strlen(src) 。所以,如果 retval >= siz, 那么由于目的缓冲区太小src被截断了.
    size_t strlcpy(char *dst, const char *src, size_t siz);
    使用 strlcpy,就不需要我们去手动负责 了,仅需要把 sizeof(dst) 告之 strlcpy 即可:
    strlcpy(path, src, sizeof(path));
    len = strlen(path);
    if ( len >= sizeof(path) )
           printf("src is truncated.");
    并且 strlcpy 传回的是 strlen(str),因此我们也很方便的可以判断数据是否被截断,但同时也给程序埋了一个雷,所以,strlcpy 并不属于 ANSI C,至今也还不是标准。

  • 相关阅读:
    【需求征集系统】打卡(五)
    【需求征集系统】打卡(五)
    《需求分析与系统设计》阅读笔记(一)
    每周总结【2020/10/24】————Redis与Mongodb初学
    【需求征集系统】打卡(四)
    【需求征集系统】打卡(三)
    初步自学Java小结
    关于“教室派”APP的使用报告和相关建议
    冲刺第一天
    结对开发之求环形数组的最大值
  • 原文地址:https://www.cnblogs.com/dyllove98/p/3144810.html
Copyright © 2020-2023  润新知