C++ 如何使用循环从另一个字符串创建没有空格的新字符串
我开始尝试编写一个函数来删除字符串中的空格,但现在我已经了解了许多其他人对这个问题的解决方案,我更想了解我的代码中到底出了什么问题/为什么C++ 如何使用循环从另一个字符串创建没有空格的新字符串,c++,string,loops,C++,String,Loops,我开始尝试编写一个函数来删除字符串中的空格,但现在我已经了解了许多其他人对这个问题的解决方案,我更想了解我的代码中到底出了什么问题/为什么std::cout 这不是那样的。使用此选项可以更改字符串的现有字符。但由于字符串为空,这会导致未定义的行为。若要附加到字符串,请将该行改为: t += s[i]; 它将打印所需的hereissometext输出。您可以找到字符串的+=运算符的文档。当您使用运算符[]插入std::string时,循环中有未定义的行为,但不确保其大小正确。您可以使用 t.pu
std::cout
这不是那样的。使用此选项可以更改字符串的现有字符。但由于字符串为空,这会导致未定义的行为。若要附加到字符串,请将该行改为:
t += s[i];
它将打印所需的hereissometext
输出。您可以找到字符串的+=
运算符的文档。当您使用运算符[]
插入std::string
时,循环中有未定义的行为,但不确保其大小正确。您可以使用
t.push_back(s[i]);
它不仅插入一个字符
,而且还确保在内部缓冲区对于新字符串来说太小时(重新)分配它
进一步注意,实际上并不需要count
变量std::string
始终跟踪其长度,因此t.size()
将始终生成当前计数的值(当然,一旦修复UB)
另一方面,复制序列中符合特定条件的部分是一项常见任务,并且存在一个特定的库模板,它可以完全做到这一点,并将您从手工制作的循环中解放出来:
#include <algorithm>
std::copy_if(s.cbegin(), s.cend(), std::back_inserter(t),
[](char c){ return std::isalpha(c); });
#包括
std::copy_if(s.cbegin()、s.cend()、std::back_inserter(t),
[](字符c){return std::isalpha(c);});
最后,还要注意@MatthieurFoltzer对std::isalpha
行为的评论,这可能值得考虑。我建议不要使用手工制作的循环。如果
与lambda表达式结合使用,则可以使用std::copy_来表示条件。这将比您的实现更稳定(如果字符串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;
}
#包括
#包括
#包括
int main(){
std::string s=“这里有一些文本”;
std::string t=“”;
自动编译=[&](常量字符c){return std::isalpha(c);};
std::copy_if(s.begin()、s.end()、std::back_inserter(t)、comp);
std::cout您的答案很好。您已经指出了一些改进,因此您还可以解释std::isalpha不仅会丢弃空格,而且会丢弃所有非字母字符。如果有与空格不同的特殊字符,它将不起作用。在您旁边,不需要定义lambda。只需将::isalpha
作为的谓词即可de>std::copy_if
(您可以使用C版本,因为std::isalpha
具有重载)@GiovanniCerretani是真的,但请注意,通常不可能在标准库中获取函数的地址-除非另有说明,否则是禁止的。虽然允许使用::isalpha
,但我认为通常最好不要接近此类非法构造。你绝对需要副本吗?你不能在plac中这样做吗e?我这样问是因为这样可以避免无数次的push_back()
操作的重复重新分配,从而将运行时间缩短约一百万倍。对于上面这样的18个字符的字符串来说,这不是什么问题,但是对于18000或18000000个字符,或者在多次执行此操作时……比如说,std::erase(std::remove_if(s.begin()、s.end()、::isspace)、s.end());
或类似?即使您确实需要副本,也最好先制作副本,然后在适当的位置进行剥离。。。
#include <algorithm>
std::copy_if(s.cbegin(), s.cend(), std::back_inserter(t),
[](char c){ return std::isalpha(c); });
#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;
}