strcpy()函数用法及其详解

strcpy()strcat()函数都有相同的问题,他们都不能检验目标空间是否能够容纳源字符串的副本。
所以,拷贝字符串用strncpy()函数更加安全

描述:

C 库函数 char *strncpy(char *dest, const char *src, size_t n)
把 src 所指向的字符串复制到 dest,最多复制 n 个字符。
当 src 的长度小于 n 时,dest 的剩余部分将用空字节填充。

声明:

char *strncpy(char *dest, const char *src, size_t n)

参数:

  • dest – 指向用于存储复制内容的目标数组。
  • src – 要复制的字符串。
  • n – 要从源中复制的字符数。

返回值:

该函数返回最终复制的字符串。

案例:该程序用strncpy()代替strcpy(),为了演示目标空间装不下源字符串的副本会发生什么情况,该程序使用了一个相当小的目标字符串(共七个元素,包含6个字符)

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define SIZE 40
#define TARGSIZE 7
#define LIM 5
char * s_gets(char *str,int n);//处理非法输入
int main()
{
    char qwords[LIM][TARGSIZE];
    char temp[SIZE];
    int i = 0;
    printf("Enter %d words beginning with q:\n",LIM);
    while(i<LIM&&s_gets(temp,SIZE))
    {
        if(temp[0]!='q')
        {
            printf("%s doesn't beginning with q.\n",temp);
        }
        else
        {
            strncpy(qwords[i],temp,TARGSIZE-1);
            /*
            因为不知道输入的有多大,所以保险起见
            我们拷贝的字符数减1,剩下一个赋值为空字符
            */
           qwords[i][TARGSIZE-1] = '\0';//末尾元素赋值为空
           i++;
        }
    }
    printf("Here are the words accepted:\n");
    for(int i = 0;i<LIM;i++)
    {
        puts(qwords[i]);
    }
    getchar();
    return 0;
}
char * s_gets(char *str,int n)//处理非法输入
{
    char *rev;
    int i = 0;
    rev = fgets(str,SIZE,stdin);
    if(rev)
    {
        while(str[i]!='\0'&&str[i]!='\n')
        {
            i++;
        }
        if(str[i]=='\n')//输入过短肯定有换行符,消除换行符
        {
            str[i] = '\0';
        }
        else
        {
            while(getchar()!='\n')
            {
                continue;
            }
        }  
    }
    return rev;
}

下面是该程序的运行示例:

Enter 5 words beginning with q:
quack
quadratic
quisling
quota
quagga

Here are the words accepted:
quack
quadra
quisli
quota
quagga

strncpy(target,source,n)source中的n个字符或空字符之前的字符(先满足哪个条件就拷贝到何处)拷贝到target中。因此,如果source中的字符数小于n,则拷贝整个字符串,包括空字符。但是,strncpy()拷贝字符串的长度不会超过n,如果拷贝到第n个字符时还未拷贝完整个源字符串,就不会拷贝空字符。所以,拷贝的副本中不一定有空字符。鉴于此,该程序把n设置为比目标数组大小少1(TARGSIZE-1),然后把数组最后一个元素设置为空字符。

strncpy(qwords[i],temp,TARGSIZE-1);
qwords[i][TARGSIZE-1] = '\0';

这样确保存储的是一个字符串。如果目标空间能够容纳字符串的副本,那么从源字符串拷贝的字符便是该副本的结尾;如果目标的空间装不下副本,则把副本最后一个元素设置为空字符。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐