从字符串中删除第一个和最后一个字符

时间:2020-01-31 19:49:59

标签: c c-strings

任务应该很简单,删除第一个和最后一个字符。

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;
}

在此先感谢您的帮助:)

3 个答案:

答案 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)

您的代码有多个问题:

  • 失败,因为您没有在目标数组的末尾设置空终止符。
  • 这很脆弱,因为您没有测试源字符串的长度至少为2个字节,从而导致较短的字符串发生不确定的行为。
  • 它是偶然编译的,因为您不包括<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;
}