从字符串中擦除单词(在C++中)
Erase words from a string (in C++)
我想从字符串中删除一些单词,但我的代码不起作用。我没有任何错误或警告,但我认为我的字符串变空了。有人能帮我吗?我尝试将我的初始字符串转换为2个矢量,这样我就可以比更容易地导航
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
int main()
{
string s("Somewhere down the road");
string t("down");
istringstream iss(s);
vector <string> plm;
vector <string> plm2;
do
{
string sub;
iss >> sub;
plm.push_back(sub);
} while (iss);
for(unsigned int i=0 ; i<plm.size();i++){
cout<<plm[i];}
istringstream ist(t);
do
{
string subb;
ist >> subb;
plm2.push_back(subb);
} while (ist);
for(int i=0;i<plm.size();i++){
for(int j=0;j<plm2.size();i++){
{if (plm[i]==plm2[j])
plm.erase(plm.begin()+j);}}}
for(int i=0 ; i<plm.size();i++)
cout<<plm[i];
}
警告:这实际上只是一个太长的注释,无法放入注释字段。哦,还有一点咆哮。
我很高兴我们有了这些现代语言,生活比几十年前轻松多了。例如,考虑一下这项工作看起来像一种早已奄奄一息的SNOBOL 4编程语言:
s = 'somewhere down the road'
del s 'down' = :s(del)
OUTPUT = s
天哪,很高兴我们从那以后取得了如此大的进步,我们不必处理整整3行代码,现在我们只需要52行就可以完成这项工作(哦,除了52行实际上不起作用,但我们暂时忽略这一点)。
我想,公平地说,我们可以在C++中更紧凑地完成这项工作。一个明显的方法是使用std::remove_copy
、一些流迭代器和一两个字符串流:
std::istringstream input("somewhere down the road");
std::string del_str("down");
std::istream_iterator<std::string> in(input), end;
std::ostringstream result;
std::remove_copy(in, end, std::ostream_iterator<std::string>(result, " "), del_str);
std::cout << result.str();
转换为向量没有任何好处——字符串本身已经提供了你想要做的事情所需的一切
vector<char> v;
v.assign(s.c_str(), s.c_str() + s.length()); // without...
v.assign(s.c_str(), s.c_str() + s.length() + ); // including...
// ... terminating null character
现在它变得很容易:
size_t pos = s.find(t);
if(pos != string::npos)
{
s.erase(pos, t.length());
}
然而,这并不关心是否留下多个空格,或者t是否不是s中的一个完整单词(例如,t = "down"; s = "I'm going to downtown.";
将导致s == "I'm going to town."
),但您也没有这样做。。。
第一个问题是,如果只使用起始位置调用std::string::erase
,它会擦除所有内容,直到字符串结束。
第二个问题是,代码只会一个接一个地擦除第二个字符串中的所有字母。也就是说,不是整个单词——为此,你需要检查整个单词是否匹配,然后才能擦除(单词的整个长度)。问问自己——如果前两个字母匹配,但单词的其余部分不匹配,代码中会发生什么?
在第二个for
循环中,您从未增加j
,并且在if (plm[i]==plm2[j])
块中,您使用j
而不是i
作为erase()
中的偏移量。
for(int i=0;i<plm.size();i++)
{
for(int j=0;j<plm2.size();j++)//here you need to increment j
{
if (plm[i]==plm2[j])
plm.erase(plm.begin()+i);//here the offset should be i
}
}
另一件事是不要使用do...while
循环从stringstream
中读取并推回向量。如果读取失败,您将把无效数据推送到矢量上,而不是尝试以下操作:
string sub;
while(iss >> sub;)
plm.push_back(sub);//only if reading is successful
...//do the same for the other istringstream too
您不递增j这是我在您的代码中看到的第一件事。把它写对,如果它仍然不起作用,那就去问!
- 文本文件中的单词链表
- 在指针的帮助下,文本文件中单词的频率
- 如何根据单词在文本中出现的概率输出单词
- 从字符串变量中逐字符读取单词
- 使用std::mt19937从字符串中返回一个随机单词
- 如何用for循环在c++中生成单词三角形
- 将数字转换为单词
- 使用if-else将数字转换为单词
- C++-字符串是否包含一个带有简单循环的单词
- 使用单词"not"作为C ++类的名称会导致VS2019错误
- 为什么这个程序返回最后一个单词而不是最长的单词?
- 3-3. 编写一个程序来计算每个不同单词在其输入中出现的次数
- C++为一串单词添加空格
- 在C++中查找(奇怪的)字符串中的单词
- 当字符串是某个单词时给出输出?
- 当您在此单词中搜索单词时调整字符数组的大小?
- 数每个单词的元音
- 我们如何在文本文件中找到C++中的几个单词?
- 使用 BFS 的单词梯 2
- 替换字符串中的单词,但忽略引号中的单词