我很惊讶在过去的十年里,没有任何一个回答提到这一点:
- 使用
strncpy(word2, word, strlen(word)-1);
复制字符串时,不包括最后一个字节是错误的:空终止符将不会设置在word2[strlen(word) - 1]
处。此外,如果word
是一个空字符串(没有最后一个字符),这段代码会导致崩溃。
strncpy
函数不适合解决这个问题。事实上,它不推荐用于任何问题,因为如果n
参数小于或等于源字符串长度,则不会在目标数组中设置空终止符。
这里有一个简单的通用解决方案,可以复制一个字符串并删除偏移量为pos
的字符,而不假设pos
是字符串内的有效偏移量:
#include <stddef.h>
char *removeat_copy(char *dest, const char *src, size_t pos) {
size_t i;
for (i = 0; i < pos && src[i] != '\0'; i++) {
dest[i] = src[i];
}
for (; src[i] != '\0'; i++) {
dest[i] = src[i + 1];
}
dest[i] = '\0';
return dest;
}
如果dest == src
,此函数也可以工作,但是为了在可修改的字符串中就地删除字符,请使用这个更高效的版本:
#include <stddef.h>
char *removeat_in_place(char *str, size_t pos) {
size_t i;
for (i = 0; i < pos && str[i] != '\0'; i++)
continue;
for (; str[i] != '\0'; i++)
str[i] = str[i + 1];
return str;
}
最后,这里是使用库函数的解决方案:
#include <string.h>
char *removeat_copy(char *dest, const char *src, size_t pos) {
size_t len = strlen(src);
if (pos < len) {
memmove(dest, src, pos);
memmove(dest + pos, src + pos + 1, len - pos);
} else {
memmove(dest, src, len + 1);
}
return dest;
}
char *removeat_in_place(char *str, size_t pos) {
size_t len = strlen(str);
if (pos < len) {
memmove(str + pos, str + pos + 1, len - pos);
}
return str;
}