【C语言经典面试题】源码实现标准库函数strncpy

架构师李肯 发表于 2022/11/30 23:35:58 2022/11/30
【摘要】 你有面试中,要求写strncpy的源码实现吗?本文给出一个参考写法!

【C语言经典面试题】源码实现标准库函数strncpy

你有面试中,要求写strncpy的源码实现吗?本文给出一个参考写法!

1 需求说明

题目大意如下:

请参考标准C库对strncpy的申明定义,使用C语言的语法写出其实现源码。

2 源码实现

2.1 函数申明

通过查看man帮助,我们可以知道strncpy函数的功能及其简要申明。

NAME
       strcpy, strncpy - copy a string

SYNOPSIS
       #include <string.h>

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

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

DESCRIPTION
       The  strcpy()  function  copies the string pointed to by src, including the terminating null byte ('\0'), to the buffer pointed to by dest.  The
       strings may not overlap, and the destination string dest must be large enough to receive the copy.  Beware of buffer overruns!  (See BUGS.)

       The strncpy() function is similar, except that at most n bytes of src are copied.  Warning: If there is no null byte among the first n bytes  of
       src, the string placed in dest will not be null-terminated.

       If the length of src is less than n, strncpy() writes additional null bytes to dest to ensure that a total of n bytes are written.

RETURN VALUE
       The strcpy() and strncpy() functions return a pointer to the destination string dest.

2.2 功能实现

以下是我的一个简单实现源码,仅供参考:

char *my_strncpy(char *dst0, const char *src0, size_t count)
{
	char *dscan;
	const char *sscan;

	dscan = dst0;
	sscan = src0;
	while (count > 0) {
	  	--count;
	  	if ((*dscan++ = *sscan++) == '\0') {
			break;
	  	}
	}

	while (count-- > 0)
		*dscan++ = '\0';

	return dst0;
}

3 源码测试

简单的测试代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static char *my_strncpy(char *dst0, const char *src0, size_t count)
{
	char *dscan;
	const char *sscan;

	dscan = dst0;
	sscan = src0;
	while (count > 0) {
	  	--count;
	  	if ((*dscan++ = *sscan++) == '\0') {
			break;
	  	}
	}

	while (count-- > 0)
		*dscan++ = '\0';

	return dst0;
}


int main(int argc, const char *argv[])
{
	char s0[10] = "123";
	char s1[10] = "123";
	char s2[] = "hello";
	char s3[] = "hello1234567890";

	printf("strcnpy    => %s\r\n", strncpy(s0, s2, 5));
	printf("my_strcnpy => %s\r\n", my_strncpy(s1, s2, 5));

	printf("strcnpy    => %s\r\n", strncpy(s0, s3, 9));
	printf("my_strcnpy => %s\r\n", my_strncpy(s1, s3, 9));

	printf("strcnpy    => %s\r\n", strncpy(s0, s3, 12));
	printf("my_strcnpy => %s\r\n", my_strncpy(s1, s3, 12));

	return 0;
}

执行编译后,运行小程序的结果:

image-20221204234932394

从运行结果上看,基本满足了题目要求,有心的读者可以进一步测试其他测试用例。

4 小小总结

  • strncpy就是执行字符串拷贝,关键还是要识别字符串的结束;
  • 示例代码中,很巧妙地利用while中的判断,简单粗暴就达到了判断字符串结束的目的;
  • 函数的返回值也是有特殊含义,切勿搞错;
  • 注意其与strcpy的主要区别在于count的传入,让函数内部知道究竟要拷贝多个字符到dst0中;但是这个函数的缺陷依然存在;那就是dst0依然有溢出的风险。

5 更多分享

架构师李肯

架构师李肯全网同名),一个专注于嵌入式IoT领域的架构师。有着近10年的嵌入式一线开发经验,深耕IoT领域多年,熟知IoT领域的业务发展,深度掌握IoT领域的相关技术栈,包括但不限于主流RTOS内核的实现及其移植、硬件驱动移植开发、网络通讯协议开发、编译构建原理及其实现、底层汇编及编译原理、编译优化及代码重构、主流IoT云平台的对接、嵌入式IoT系统的架构设计等等。拥有多项IoT领域的发明专利,热衷于技术分享,有多年撰写技术博客的经验积累,连续多月获得RT-Thread官方技术社区原创技术博文优秀奖,荣获CSDN博客专家CSDN物联网领域优质创作者2021年度CSDN&RT-Thread技术社区之星2022年RT-Thread全球技术大会讲师RT-Thread官方嵌入式开源社区认证专家RT-Thread 2021年度论坛之星TOP4华为云云享专家(嵌入式物联网架构设计师)等荣誉。坚信【知识改变命运,技术改变世界】!

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区),文章链接,文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至:cloudbbs@huaweicloud.com进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。