【问题标题】:C++ remove function moving characters to the left [duplicate]C ++删除函数将字符向左移动[重复]
【发布时间】:2021-01-10 20:38:45
【问题描述】:

我最近尝试使用此站点某处提到的代码来删除字符串中的空格。答案建议从算法库中删除函数(在这里解释得很奇怪:https://www.geeksforgeeks.org/stdremove-stdremove_if-c/),但它给出了意外的输出。它用一些随机数替换所有空格。这是代码。

#include <iostream>
#include <algorithm>
using namespace std;

int main() 
{
string a;
int b;
getline(cin, a);
remove(a.begin(), a.end(), ' ');
b = stoi(a);
cout << b << endl;
return 0;
}

例如,如果我输入 14 546 32,它会输出 145463232。奇怪的是,如果我输入 1 2 3 4 5,它会输出正确的东西:12345。

预期输出,输入:

我输入任何数字之间有空格的数字。

输出不带空格的数字。

我尝试使用此编译器在线编译它:https://www.onlinegdb.com/。它具有完全相同的输出。任何人都可以弄清楚代码有什么问题。而且我还需要将字符串转换为整数,然后对整数进行一些数学运算(这就是我使用 stoi 函数的原因)。谢谢。

【问题讨论】:

  • onlinegdb 是一个简洁的工具。您是否使用它来逐步执行程序以查看行为偏离您期望的地方?在寻找错误时非常有用。
  • @user4581301 你好,你的意思是我应该使用调试器。如果我问的是愚蠢的问题,我对这些东西很抱歉。
  • 引用 cppreference 从范围 [first, last) 中删除所有满足特定条件的元素,并为范围的新结束返回一个过去的迭代器。它会从范围中删除您不想要的东西。不是从字符串。典型用法是在 remove 返回的迭代器上调用 erase 以实际删除(是的。我知道这听起来很愚蠢,整个 remove 没有删除东西)字符串中不需要的字符。
  • 一本好的 C++ 教科书不仅会解释 std::remove 的作用,还会给出几个正确使用它的示例,这将清楚地说明所显示的代码还缺少哪些其他附加步骤。
  • @user4581301 我研究了擦除和删除功能之间的区别,现在我知道问题出在哪里了。感谢所有花时间回答我的问题或发表评论的人的帮助。

标签: c++ clion


【解决方案1】:

关于 std::remove 的有趣之处在于它实际上并没有删除任何东西。 =)

你需要像这样自己擦除角色:

#include <iostream>
#include <algorithm>
using namespace std;

int main() 
{
    string a;
    int b;
    getline(cin, a);
    a.erase(remove(a.begin(), a.end(), ' '), a.end());
    b = stoi(a);
    cout << b << endl;
    return 0;
}

您可以在此处阅读更多关于 Erase–remove 的信息: https://en.wikipedia.org/wiki/Erase%E2%80%93remove_idiom

【讨论】:

  • 您好,非常感谢您抽出宝贵的时间来回答,但即使这样也行不通。我输入了 78 789 90,它输出了 78789900。它最后添加了一个不必要的零。你能解释一下为什么会这样吗?谢谢。
  • @Phaeton 上面的代码应该可以工作,所以我试了一下,得到了预期的结果:ideone.com/TiVJhT
  • @user4581301 非常感谢。我在编写代码时一定犯了复制粘贴错误。你的答案有效。谢谢。
  • 太棒了!如果您愿意,可以将我的答案标记为答案:)
  • @Arseniy 是的,我现在就这样做。感谢您抽出宝贵时间回答我的问题。
【解决方案2】:

std::remove 通过使用移动赋值移动剩余元素来删除比较等于其参数的元素。移动这些元素后,它不会调整容器的大小。在您的情况下,由于对象的类型为char,因此它们被简单地复制到数组的开头。所以你的字符串的结尾保持不变。

当您从第一个数字中删除空格并将所有内容向左移动时,您会得到:

old string: 14 546 32
new string: 145463232

当你在第二种情况下做同样的事情时:

old string: 1 2 3 4 5
new string: 12345 4 5

您在第二个中得到正确结果的唯一原因是中间的空格。字符串中的第一个数字 (12345) 被转换为 int 并返回。

注意std::remove 也返回一个迭代器到列表的新end。您可以使用它来调整字符串的大小。

auto end = remove(a.begin(), a.end(), ' ');
a.resize(end - a.begin());

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多