#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
int main()
{
string str;
cin>>str;
str.erase(remove_if(str.begin(), str.end(), isspace),str.end());
cout<<str;
return 0;
}
错误味精:
/home/satish/Desktop/CPP/Remove_Spaces/main.cpp|9|error:没有用于调用'remove_if(std :: basic_string :: iterator,std :: basic_string :: iterator,)'的匹配函数
答案 0 :(得分:4)
首先,在std::isspace
中宣布<cctype>
,所以请包含该内容。
其次,您需要通过将函数转换为显式类型来消除重载的歧义:
str.erase(
remove_if(str.begin(), str.end(), static_cast<int(*)(int)>(isspace)),
str.end());
第三,正如James所说,这会导致所有不在ASCII范围内的字符的未定义行为,并且由于您通常不能排除这种情况,因此您需要努力确保只将正字符代码传递给{ {1}}:
std::isspace
答案 1 :(得分:3)
正如评论中所述,您缺少std::isspace
的包含,即<cctype>
。但即便如此,你也不会有成功,因为isspace被重载see here。
过载问题的解决方案是将函数指针显式地转换为所需的函数sgnature:
str.erase(remove_if(str.begin(), str.end(), static_cast<int(*)(int)>(&std::isspace)),str.end());
但是,正如评论中所指出的那样,此处使用的isspace
具有未定义的行为,如果它获得非ASCII字符。在这种情况下,最好使用模板化版本将语言环境作为第二个参数:
<强> C ++ 14:强>
str.erase(
remove_if(str.begin(), str.end(),
[](auto c){ return isspace(c, cin.getloc());}
),
str.end());
C ++ 11:,如上所述,lambda以char c
为参数(C ++ 11中没有多态lambda)。
C ++ 03 with boost:使用boost::bind
为remove_if
创建谓词
str.erase(
remove_if(str.begin(), str.end(),
boost::bind(&std::isspace<char>, _1, boost::ref(cin.getloc()))
),
str.end());
没有提升的C ++ 03:将手写的仿函数定义为谓词
struct IsSpace {
bool operator()(char c) {
return std::isspace(c, cin.getloc());
}
};
str.erase(
remove_if(str.begin(), str.end(),
IsSpace()
),
str.end());
答案 2 :(得分:1)
由于到目前为止所有答案都涉及未定义的行为......
“最简单”的解决方案,如果您使用C ++ 11, 是:
str.erase(
std::remove_if(
str.begin(),
str.end(),
[]( char ch ) { return isspace( static_cast<unsigned char>( ch ) ); } ),
str.end() );
如果没有转化为unsigned char
,isspace
的输入就会出现
失败的(未经检查的)函数的前提条件是明确的
char
已签名。
如果您没有C ++ 11,或者您将需要这种类型 你在其他地方的东西(跳过空白等) 可以写一个单独的谓词功能对象:
struct IsSpace
{
bool operator()( char ch ) const
{
return isspace( static_cast<unsigned char>( ch ) );
}
};
您可能还需要IsNotSpace
和相应的对象
其余is...
函数位于<ctype.h>
。
或者,您可以使用的语言环境感知版本
<locale>
中的函数:
template <std::ctype_base>::mask mask, bool is>
class Is
{
std::locale m_toEnsureLifetime;
std::ctype<char> const* m_ctype;
public:
Is( std::locale const& l = std::locale() )
: m_toEnsureLifetime( l )
, m_ctype( &std::use_facet<std::ctype<char>>( m_toEnsureLifetime ) )
{
}
bool operator()( char ch ) const
{
return m_ctype->is( mask, ch ) == is;
}
};
typedef Is<std::ctype_base::space, true> IsSpace;
typedef Is<std::ctype_base::space, false> IsNotSpace;
// ...
虽然有点复杂,但它完全可以识别语言环境,并且 实际上需要更少的代码(因为掩码可以是一个模板 参数)。
答案 3 :(得分:0)
尝试这种方式:
#include <iostream>
#include <string>
#include <algorithm>
struct SpaceRemover
{
bool operator( )( char _ch ) { return std::isspace( _ch ); }
};
int main( )
{
std::string strSource = " type ddd ";
std::cout << "[main] Source string :\""<< strSource << "\"" << std::endl;
std::string::iterator itEnd = std::remove_if( strSource.begin(),
strSource.end(),
SpaceRemover( ) );
strSource.resize( std::distance( strSource.begin(), itEnd ) );
std::cout << "[main] Result string :\""<< strSource << "\"" << std::endl;
return 0;
}
答案 4 :(得分:0)
#include <iostream>
int main() {
std::string original = " type ddd ";
std::string result;
for(char c: original) {
if( ! std::isspace(c)) result += c;
}
original.swap(result);
std::cout << "Modified: " << original << std::endl;
return 0;
}
如果可以预测结果大小(或者仅仅考虑原始大小),result.reserve()将提高性能。