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

g_h*_*g_h 9 c++ string loops

我开始尝试编写一个函数,该函数将从字符串中删除空格,但是现在,我已经研究了许多其他人针对该问题的解决方案,而我只是想确切地了解代码中出了什么问题/为什么std::cout << t << std::endl;末尾什么都不输出。

当我std::cout << t[count];在循环中包含该语句(在下面注释掉的语句)时,它将正确输出到控制台:hereissometext无空格。当我std::cout << t[0] << std::endl;结束时,它正确输出ht[1]as et[2]as 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;
Run Code Online (Sandbox Code Playgroud)

lub*_*bgr 12

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

t.push_back(s[i]);
Run Code Online (Sandbox Code Playgroud)

这不仅会插入一个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); });
Run Code Online (Sandbox Code Playgroud)

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

  • 你的回答很好。您已经指出了一些改进,因此您还可以说明std :: isalpha不仅会丢弃空间,还会丢弃所有非字母字符。如果特殊字符与空格不同,它将不起作用。 (6认同)
  • @GiovanniCerretani是的,但是请注意,通常无法在标准库中获取函数的地址-除非另有说明,否则禁止这样做。虽然可能允许使用:: isalpha,但我认为最好不要接近这种非法构造。 (2认同)

Bla*_*aze 6

t[count]+=s[i];
Run Code Online (Sandbox Code Playgroud)

这样不行。这样,您可以更改字符串的现有字符。但是,由于您的字符串为空,因此会导致未定义的行为。要附加到字符串,请将该行改为:

t += s[i];
Run Code Online (Sandbox Code Playgroud)

并输出所需的输出hereissometext。您可以在此处找到+=字符串操作员的文档。


sch*_*312 5

我建议不要使用手工制作的循环。您可以将其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;
}
Run Code Online (Sandbox Code Playgroud)