自定义ft_strncpy与同学实现差异排查:为何测试不通过?
我的ft_strncpy与正确实现的差异场景分析
问题背景
我需要不依赖任何库实现C语言的strncpy函数,编写的ft_strncpy提交后被判错误。附上测试diff结果和同学的正确实现,想找出两个函数产生不同输出的输入场景,之前问过同学和多个AI都没找到。
我的实现代码
char *ft_strncpy(char *dest, char *src, unsigned int n) { unsigned int i; i = 0; while (i < n) { if (src[i]) dest[i] = src[i]; else dest[i] = '\0'; i++; } return (dest); }
同学的正确实现代码
char *ft_strncpy(char *dest, char *src, unsigned int n) { unsigned int i; i = 0; while (i < n && src[i] != '\0') { dest[i] = src[i]; i++; } while (i < n) { dest[i] = '\0'; i++; } return (dest); }
测试diff结果
$> diff -U 3 user_output_test1 test1.output | cat -e --- user_output_test1 2024-03-20 15:16:50.490408519 +0000$ +++ test1.output 2024-03-20 15:16:50.470408242 +0000$ @@ -2,69 +2,69 @@$ 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004d6b4c6156524a4e4f64505a6d62724d$ 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004d6b4c61524256466c575441675a444f$
差异场景分析
两个函数的核心差异在于当src字符串中间包含'\0'字符时的处理逻辑:
- 你的代码:在每一轮循环中都会检查当前
src[i]是否非0,即使之前已经遇到过'\0',只要i还没到n,就会继续处理src后续的字符——如果src[i]非0就拷贝,是0就填'\0'。 - 正确实现(同学代码):一旦遇到src中的第一个'\0',就停止拷贝src的字符,直接将dest剩余的位置全部填充为'\0',不会再处理src中'\0'之后的内容。
这完全符合标准strncpy的定义:strncpy仅拷贝src中第一个'\0'之前的字符,剩余的目标位置用'\0'填充,不会处理src中第一个'\0'之后的任何字符。
具体示例
假设src = "abc\0def",n = 7:
- 你的代码输出:
dest内容为"abc\0def",会把src中'\0'后面的'd'、'e'、'f'继续拷贝到dest中。 - 正确实现输出:
dest内容为"abc\0\0\0\0",遇到src的'\0'后直接填充剩余位置为'\0'。
从测试diff的十六进制结果也能验证这一点:你的输出包含了src中'\0'之后的字符,而正确输出没有,这就是导致测试不通过的原因。
内容的提问来源于stack exchange,提问作者sambensim
相关产品推荐
相关产品推荐

