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

Strip first and last character from C string

我有一个c字符串,看起来像"Nmy stringP",其中n和p可以是任何字符。如何在C中编辑成"my string"


要"删除",第一个字符指向第二个字符:

1
2
3
char mystr[] ="Nmy stringP";
char *p = mystr;
p++; /* 'N' is not in `p` */

若要删除最后一个字符,请将其替换为""

1
p[strlen(p)-1] = 0; /* 'P' is not in `p` (and it isn't in `mystr` either) */


另一个选项,再次假设"编辑"意味着要就地修改:

1
2
3
4
5
6
void topntail(char *str) {
    size_t len = strlen(str);
    assert(len >= 2); // or whatever you want to do with short strings
    memmove(str, str+1, len-2);
    str[len-2] = 0;
}

这将在适当的位置修改字符串,而不会像PMG的解决方案那样生成新地址。不是说PMG的回答有什么问题,但在某些情况下,这不是你想要的。


关于@pmg的答案,请注意,您可以在一个语句中同时执行这两个操作:

1
2
3
char mystr[] ="Nmy stringP";
char *p = mystr;
p++[strlen(p)-1] = 0;

这可能如预期的那样工作,但行为在C标准中是未定义的。


最有效的方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//Note destroys the original string by removing it's last char
// Do not pass in a string literal.
char * getAllButFirstAndLast(char *input)
{
  int len = strlen(input);
  if(len > 0)
    input++;//Go past the first char
  if(len > 1)
    input[len - 2] = '\0';//Replace the last char with a null termination
  return input;
}


//...
//Call it like so
char str[512];
strcpy(str,"hello world");
char *pMod = getAllButFirstAndLast(str);

最安全的方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void getAllButFirstAndLast(const char *input, char *output)
{
  int len = strlen(input);
  if(len > 0)
    strcpy(output, ++input);
  if(len > 1)
    output[len - 2] = '\0';
}


//...
//Call it like so
char mod[512];
getAllButFirstAndLast("hello world", mod);

第二种方法效率较低,但更安全,因为您可以将字符串文本传入输入。如果不想自己实现,也可以使用strdup作为第二种方法。