You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何不借助临时变量,用<cstring>库实现字符数组指定索引右移?

字符串指定位置右移的问题分析与解决方案

为什么strcpy(str+i, str+j)(i>j)不符合预期?

strcpy的设计不支持重叠内存区域的复制。当目标指针(str+i)位于源指针(str+j)右侧时,strcpy会从左到右依次复制字节:先将str[j]覆盖到str[i],接着复制str[j+1]到str[i+1]——但此时str[j+1]可能已经被之前的复制操作覆盖(因为i>j,j+1可能等于i),后续复制的都是已经被修改过的数据,最终导致字符串出现连续重复的错误内容,就像你代码里的Welccccccco hell!!。

可行的实现方法(无需辅助变量,用库)

使用<cstring>中的memmove函数,它专门针对重叠内存区域做了优化:会先判断源和目标的位置关系,如果目标在源右侧,就从字符串末尾开始向左复制,避免覆盖未复制的源数据。

代码示例(实现你的预期效果:将Welcome改为Welccome)

#include <iostream>
#include <cstring>

using namespace std;

int main()
{
    char str[100] = "Welcome to hell!";
    int insert_pos = 4; // 要插入字符的位置(即右移的起始位置)
    size_t str_len = strlen(str);

    // 将insert_pos开始的所有字符(包括'\0')右移一位
    // 第三个参数是要复制的字节数:原长度 - 起始位置 + 1(包含终止符)
    memmove(str + insert_pos + 1, str + insert_pos, str_len - insert_pos + 1);
    // 把前一个位置的字符复制到腾出的位置,实现插入效果
    str[insert_pos] = str[insert_pos - 1];

    cout << str; // 输出:Welccome to hell!
    return 0;
}

其他替代方案

如果不想用memmove,也可以手动从后往前遍历复制,原理和memmove一致:

#include <iostream>
#include <cstring>

using namespace std;

int main()
{
    char str[100] = "Welcome to hell!";
    int insert_pos = 4;
    size_t str_len = strlen(str);

    // 从字符串终止符开始,往前逐个将字符右移一位
    for (size_t i = str_len + 1; i > insert_pos; --i) {
        str[i] = str[i - 1];
    }
    str[insert_pos] = str[insert_pos - 1];

    cout << str; // 输出:Welccome to hell!
    return 0;
}

内容的提问来源于stack exchange,提问作者oomertaa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 11:26:32