如何在没有临时值的情况下移动字符数组中的字符?

问题描述 投票:0回答:2

我想知道是否有任何方法可以将索引中的所有字符向右移动一个位置,前提是为其分配了足够的空间。

我的老师暗示我可以在没有辅助变量的情况下使用

<cstring>
库来完成。

我尝试过:

#include <iostream>
#include <cstring>

using namespace std;

int main()
{
    char str[100] = "Welcome to hell!";
    strcpy(str+4, str+3);
    cout << str; //Welccccccco hell!!
                 //Expected: Welccome to hell (to double the c so i can insert whitespace)
    return 0;
}

我知道这个函数使用指针作为参数,因此使用相同的字符串调用它可能会把事情搞砸。但这在某种程度上可能吗?我发现如果 i > j,strcpy(s+i, s+j) 会给出意想不到的结果。为什么?另外,有什么替代方案吗?

c++ arrays string char c-strings
2个回答
0
投票

strcpy(str+4, str+3);
str+3
读取字符,直到找到
\0
。但是,它从一个位置读取一个字符,然后写入数组中的下一个位置,因此它永远找不到
\0
。更正式地正确:
strcpy(str+4,str+3)
调用未定义的行为。代码的输出可以是任何内容。

您可以使用

std::copy
,只要源范围的开始位于目标范围之外即可:

int main()
{
    char str[100] = "Welcome to hell!";
    std::copy(str+3,str+std::strlen(str),str+4);
    cout << str;
}

现场演示

请注意,通过将字符串末尾显式传递给

strcpy
可以避免
std::copy
必须到达字符串末尾的问题。


0
投票

来自 cppreference

如果字符串重叠,则行为未定义。

您是否习惯使用 C 弦?使用

std::string
可以做到这一点:

std::string string("Welcome to hell!");
std::cout << string.insert(3, " ");

为了避免在插入时复制整个字符串,因为需要更多内存,您可以调用

reserve
提前告诉字符串需要多少空间:

std::string string;
string.reserve(100);
string = "Welcome to hell!";
© www.soinside.com 2019 - 2024. All rights reserved.