strcpy/strcat && strncpy/strncat && strlcpy/strlcat 总结

本文详细解析了C语言中常见的字符串操作函数,如strcpy、strncpy、strcat、strncat等的功能及使用方法,并对比了strlcpy与strlcat的优势,帮助读者避免内存越界等常见错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

(1)       strcpy/strcat  strncpy/strncat  比较

复制:

a .  char* strcpy( char* dest, char* src ) ;

         // 复制 src dest 字符串中; src 结束的标志是 ’/0’

i 测试    

char* p="how are you ?";

    char name[20]="ABCDEFGHIJKLMNOPQRS";

              strcpy(name, p); 

 

结果 // 正确! name=” how are you ?” , 因为 p 包含结束符 ’/0’

 

  ii 测试:

        char src[10];

       src[0] = ‘A’;

       src[1] = ‘L’;

       src[2] = ‘I’;

       char name[20]="ABCDEFGHIJKLMNOPQRS";

       strcpy(name, src);

   结果: // 不确定! name 值不确定 , src 结束符不确定在哪儿

   若: memset( src, 0, sizeof(src) ); 或者 src[3] = ‘/0’ ,即确定结束符,则复制结果正确

 

  b.  char* strncpy( char* dest, char* src,  int n );

         // 复制 src 的前 n 个字符到 dest 中;如果前 n 个字符没有结束符,则结尾不会有结束符:

  i . 测试:

char* p="how are you ?";

    char name[20]="ABCDEFGHIJKLMNOPQRS";

   strncpy(name, p strlen(p)+1 );  

结果 // 正确! name=” how are you ?” 包含结束符

 

若: strncpy(name, p strlen(p) );

结果 // 错误! name=” how are you ?NOPQRS” 因为未复制结束符

name[strlen(p)+1] = ‘/0’;  // 正确: name=” how are you ?”

 

ii . 测试:

        char src[50];

       src[0] = ‘A’;

       src[1] = ‘L’;

       src[2] = ‘I’;

       char name[20]="ABCDEFGHIJKLMNOPQRS";

       strncpy(name, src 3);

       name[4] = ‘/0’;

结果 // 正确! name=” how are you ?”

 

        若: char* src  = “HELLO WORLD”;

                  char des[1024];

                  strncpy( des, src, 1024 );

结果 // 正确! des=” HELLO WORLD +’/0’+…+ 将近 1000 ’/0’”

      

// 结论: strncpy 指定了 copy 的长度,避免了 strcpy 一直往后找 ’/0’ 的情况,避免了内存越界;

 

    字符串连接:

a.       char* strcat( char*dest, char* src );

      // 复制 src dest 的末尾

b.       char* strncat( char* dest, char* src, int n );

                // 复制 src n 个字符到 dest 末尾,然后加 ’/0’ ;若 n>strlen(src) ,则 copy 整个 src

       c 越界:

 

 

          测试:

        char* p="how are you ?";

                char name[20]="ABCDEFGHIJKLMNOPQRS";

               strcat( name, p );

         结果 // 错误! name=”ABCDEFGHIJKLMNOPQRShow are you ?” 越界,造成相邻内存被覆盖

 

测试:

        char* p="how are you ?";

               char name[20]="ABCDEFGHIJKLMNOPQRS";

               strncat( name, p strlen(p) );    //code

        结果 // 错误! name=”ABCDEFGHIJKLMNOPQRShow are you ?” 越界,造成相邻内存被覆盖

                  修改 code ①为: strncat( name, p, sizeof(name)-strlen(name)-1 );

                  结果 // 正确! name=”ABCDEFGHIJKLMNOPQRS” ,无内存越界

(2)       strlcpy/strlcat

     size_t strlcpy(char *dst, const char *src, size_t size);

     size_t strlcat(char *dst, const char *src, size_t size);

     两个函数均返回最终字符串长度,若返回长度 >sizeof(dst) ,则发生了截断,需要新增字符串缓存;同时 strlcpy 不会像 strncpy 那样有多余的 ’/0’ ,比 strncpy 效率要高

测试:

           char name[20]="ABCDEFGHIJKLMNOPQRS";

           char str[5];

           int len = strlcpy( str, name, sizeof(str) );

            if( len > sizeof(str) ){

    printf( “ 产生截断 /n” );

}

结果:      //str = “ABCD”; 若想判断是否截断,查看 strlcpy 返回值

 

测试:

        char* p="how are you ?";

             char name[20]="ABCDEFGHIJKLMNOPQRS";

           int len = strlcat( name, p, sizeof(name) );

            if( len > sizeof(name) ){

              printf(“Array too short!/n”);

}

           结果:      //name = “ ABCDEFGHIJKLMNOPQRS ”; len(32) > sizeof(name)(20)

                      // 避免了内存覆盖

 

     源代码:

   strlcpy/strlcat 应用情况:

         用于处理固定大小的 C 字符串;如果写的字符串支持动态分配的,任意大小的缓冲区,那就需要考虑看一下源码了, O( _ )O~

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值