任务应该很简单,删除第一个和最后一个字符。
https://www.codewars.com/kata/56bc28ad5bdaeb48760009b0/train/c
该函数获取两个参数(dst
作为目标,src
作为源),并且应该返回修改后的字符串并分配给dst
指针(如果我理解正确的话)。
我的答案对我来说似乎是正确的,但这是我的问题:
当字符串的字符数超过9个时,修改后的字符串会带有一些符号。
char* remove_char(char* dst, const char* src){
memmove(dst,src+1,strlen(src+1)-1);
return dst;
}
在此先感谢您的帮助:)
答案 0 :(得分:6)
这样做时:
memmove(dst,src+1,strlen(src+1)-1);
您正确地跳过了第一个和最后一个字符,但是最后得到的字符串没有NUL终止符(\0
)。您应该在memmove
之前或之后自行添加:
size_t len = strlen(src) - 2;
memmove(dst, src + 1, len);
dst[len] = '\0';
当然,以上所有代码均假设dst
已正确分配并且可以包含至少strlen(src) - 1
个字符,并且src
至少具有2
个字符。< / p>
如果您还想考虑src
小于两个字符的边缘情况:
size_t len = strlen(src);
if (len < 2) {
*dst = '\0';
} else {
memmove(dst, src + 1, len - 2);
dst[len - 2] = '\0';
}
return dst;
注意:您可能必须#include <stddef.h>
才能使用size_t
。
答案 1 :(得分:3)
此通话
memmove(dst,src+1,strlen(src+1)-1);
不会在指针dst指向的字符数组中创建字符串,因为不会复制终止的零,并且目标数组也无法初始化为零。
表达式strlen( src + 1 ) - 1
也可以调用未定义的行为。
如果字符数组没有重叠,则没有必要使用记忆。
这里是一个演示程序,显示了如何执行任务。
#include <stdio.h>
#include <string.h>
char * remove_char( char * restrict dst, const char * restrict src )
{
size_t n = strlen( src );
n = n < 2 ? 0 : n - 2;
if ( n != 0 )
{
memcpy( dst, src + 1, n );
}
dst[n] = '\0';
return dst;
}
int main(void)
{
enum { N = 10 };
char dst[N];
printf( "\"%s\"\n", remove_char( dst, "" ) );
printf( "\"%s\"\n", remove_char( dst, "1" ) );
printf( "\"%s\"\n", remove_char( dst, "12" ) );
printf( "\"%s\"\n", remove_char( dst, "121" ) );
return 0;
}
程序输出为
""
""
""
"2"
答案 2 :(得分:0)
您的代码有多个问题:
<string.h>
,因此在没有适当原型的情况下调用函数。编译器推断出的原型不正确。在代码战在线编译器上发布的 Solution 应该作为独立文件进行编译。它必须包含相关文件,例如,如果您使用<string.h>
或memmove()
,则strlen()
。
这是一个更正的解决方案:
#include <string.h>
char *remove_char(char *dst, const char *src) {
size_t len = strlen(src);
if (len >= 2) {
memmove(dst, src + 1, len - 2);
dst[len - 2] = '\0';
} else {
*dst = '\0';
}
return dst;
}