如何使用循环从另一个字符串创建一个没有空格的新字符串

How to create a new string without spaces from another string using a loop

本文关键字:字符串 一个 空格 循环 何使用 另一个 创建      更新时间:2023-10-16

我开始尝试编写一个可以从字符串中删除空格的函数,但现在我已经查看了许多其他人对该问题的解决方案,我更只是试图确切地了解我的代码中出了什么问题/为什么最后的std::cout << t << std::endl;没有输出任何内容。

当我在循环中包含std::cout << t[count];时(下面注释掉的语句(,它会正确地输出到控制台:hereissometext没有空格。当我在最后std::cout << t[0] << std::endl;时,它会正确输出ht[1] et[2] r,依此类推。但是,当我尝试在最后输出t时,它会输出空格,t.size()输出0

我对编码相当陌生,所以如果这是一个完全明显的问题,请原谅我。

    std::string s = "here is some text";
    std::string t = "";
    int count = 0;
    for (int i = 0; i < s.size(); i++) {
        if (std::isalpha(s[i])) {
            t[count]+=s[i];
            // std::cout << t[count];
            count++;
        }
    }
    std::cout << t << std::endl;

循环中存在未定义的行为,因为您使用operator[]插入std::string,而不确保其大小正确。您可以改用

t.push_back(s[i]);

这不仅插入了一个char,而且还确保内部缓冲区在对于新字符串来说太小时被(重新(分配。

进一步请注意,您实际上并不需要 count 变量。 std::string始终跟踪其长度,因此t.size()将始终产生当前count的值(当然,一旦您修复了UB(。

顺便说一句,复制序列中与特定条件匹配的部分是一项常见任务,并且存在一个特定的库模板可以做到这一点,并将您从手工制作的循环中解放出来:

#include <algorithm>
std::copy_if(s.cbegin(), s.cend(), std::back_inserter(t),
     [](char c){ return std::isalpha(c); });

最后,还要注意@MatthieurFoltzer对std::isalpha行为的评论,这可能值得考虑。

t[count]+=s[i];

这不是那样工作的。有了这个,您可以更改字符串的现有字符。但由于您的字符串为空,这会导致未定义的行为。若要追加到字符串,请将该行更改为以下内容:

t += s[i];

它将打印所需的输出 hereissometext .您可以在此处找到字符串的+=运算符的文档。

我建议不要使用手工制作的循环。您可以将std::copy_if与 lambda 表达式结合使用来表述您的条件。这将比你的实现更稳定(如果字符串s的长度超过int的容量会发生什么?我认为这也增强了可读性。

#include <algorithm>
#include <iostream>
#include <string>
int main() {
    std::string s = "here is some text";
    std::string t = "";
    auto comp = [&](const char c) { return std::isalpha(c); };
    std::copy_if(s.begin(), s.end(), std::back_inserter(t), comp);
    std::cout << t << std::endl;
}
相关文章: