使用 str.erase() 的索引擦除字符串的元素?

Erasing an element of a string using an index with str.erase()?

本文关键字:擦除 字符串 元素 索引 使用 erase str      更新时间:2023-10-16

如何使用erase()方法以str.erase(str[i])的形式擦除std::string"str"的一部分?

当我运行下面的代码时,它只输出字符串减去第一个元素,然后是一些奇怪的字符。

#include<bits/stdc++.h>
using namespace std; 
int main()
{
string s;
cout << "Please input the desired string : n";
cin >> s;
int sz = sizeof s;
int x = sz / 2;
if ((sizeof s)%2 != 0)
{
s.erase(s[x]);
}
else
{
s.erase(s[x-1], s[x]);
}
for (int j=1; j <= sz; j++)
{
cout << s[j];
}    
}

std::string::erase()方法有几个重载:

basic_string& erase( size_type index = 0, size_type count = npos );
iterator erase( iterator position );
iterator erase( const_iterator position );
iterator erase( iterator first, iterator last );
iterator erase( const_iterator first, const_iterator last );

s.erase(s[x])调用第一个重载,s[x]视为index(因为char可隐式转换为std::string::size_type)。

首先,s[x]不是有效的索引(不过,x单独是),所以这是未定义的行为

其次,您没有显式指定count参数的值,因此使用默认值npos,它告诉erase()删除所有字符,包括指定index之后的字符,这可能不是您想要的(或者它?您是要仅删除index处的 1char,还是index的所有char

s.erase(s[x-1], s[x])还调用第一个重载(隐式将 2char秒转换为size_type秒)。 同样,您传入的char不是有效的索引或计数,因此这也是未定义的行为

您的代码中还存在其他问题。

sizeof s返回s的字节大小(即std::string类本身的大小),而不是s包含的字符数据的长度。 这些字符存储在内存中的其他位置(除非您输入一个小字符串,并且您的 STL 实现std::string采用小字符串优化)。使用s.length()s.size()获取字符数据的长度。

您看到意外的输出std::string因为索引从 0 开始,而不是从 1 开始。 你的for循环跳过s中的第一个字符,并越过s的末尾进入周围的记忆,这也是未定义的行为。 更重要的是,当你调用s.erase()时,你正在修改s的长度,但你没有更新你的sz变量来反映新的长度,所以你的for循环可能会超过s的结束。

话虽如此,请尝试更多类似的东西:

#include <iostream>
#include <string>
using namespace std; 
int main()
{
string s;
cout << "Please input the desired string : n";
cin >> s;
size_t sz = s.length();
size_t x = sz / 2;
if ((sz % 2) != 0)
{
s.erase(x, 1);
}
else
{
s.erase(x-1, 2); // or (x-1, 1)? What do you want to erase exactly?
}
sz = s.length();
for (int j = 0; j < sz; ++j)
{
cout << s[j];
}    
return 0;
}