strcpy(s+i, s+i+1) 是什么意思?

时间:2021-02-24 17:04:56

标签: c++ string

我有这段代码:

int i = 0;
char s[12];
strcpy(s,"abracadabra");
cout << strlen(s);
while(i < strlen(s))
{
    if (s[i]=='a') strcpy(s+i, s+i+1);
    else i++;
}
cout << " " << s;

但我不明白为什么输出是 brcdbr

我认为 s+i 的意思是 s[n+i] 或类似的意思?

有人可以向我解释这是如何工作的吗?

2 个答案:

答案 0 :(得分:0)

在您的终端输入 man strcpy

<块引用>

char *strcpy(char *dest, const char *src);

<块引用>

strcpy() 函数复制 src 指向的字符串, 包括终止空字节 ('\0'),到指向的缓冲区 到 dest。 字符串不能重叠,目的地 字符串 dest 必须足够大以接收副本。提防 缓冲区溢出! (请参阅错误。)

所以你正在从你的字符串中复制所有字节,

  • 从 src:索引 i + 1('a' 之后的下一个字母)到 '\0'
  • 到 dest:索引 i(字母 'a')到 '\0'

注意:正如评论中所述,摆脱“a”是一种非常低效的方式和未定义的行为,但我猜你是来这里解释s+i的,这意味着{{1} } 甚至 &s[i]

阅读有关“指针算法”的更多信息

如果您想要一种有效的方式,请查看 this post

答案 1 :(得分:0)

<块引用>

有人可以向我解释这是如何工作的吗?

它不起作用,程序的行为是undefined。关于结果没有任何意义可言(即使在某些特定情况下看起来是正确的)。

例如,在 godbolt 上,输出不是 brcdbr 而是 brcdrr

那是因为使用重叠的源指针和目标指针调用 strcpy 是非法的:

<块引用>

C11 §7.24.2.3 strcpy 函数

strcpy 函数复制 s2 指向的字符串(包括 终止空字符)到 s1 指向的数组中。 如果 复制发生在重叠的对象之间,行为是 未定义。

(注意:C++ inherits C 标准库函数的 C 规则)

无论如何,如果您只是想知道 strcpy(s+i, s+i+1) 背后的意图,在 C++ 表达式中,数组会自动衰减到一个指针。所以 char s[12] 变成了 char* s。然后表达式 s+i 变成指针算术 - 取 ith 元素指向的地址 s。相当于写&s[i],即取isth元素的地址。这同样适用于 s+i+1 - 它计算为指向 i+1 中的 sth 元素的指针。 strcpy 调用的目的是将字符串 after a 的剩余部分复制到内存 are starting at a,即,将剩余的字符向前移动一位,从而覆盖a

在 C++ 中更好的方法是使用 std::stringerase-remove idiom 从字符串中删除字符 a

#include <iostream>
#include <algorithm>
#include <string>

int main() {
    std::string s = "abracadabra";
    s.erase(std::remove(s.begin(), s.end(), 'a'), s.end());
    std::cout << s << std::endl;
}

打印:

brcdbr