是否有任何简单的机制可以跳转到具有C ++输入流的下一个空格(如ifstream
)?
我知道如果我知道要跳过多少个字符或预期的分隔符,我可以使用ignore
。但IMO在ignore
通常只读取下一个空格而不提供任何其他参数时使用operator>>
是很难看的。我也可以使用假人,但这只会让事情变得更糟。
auto importantInfo1 = 0;
auto importantInfo2 = 0;
auto someDummy = 0; // This is ugly and doesn't clearly express the intent
file >> importantInfo1 >> someDummy >> importantInfo2;
同样在某些情况下,如果我需要在“skip”-case中处理不同的数据类型,我将需要多个虚拟对象。
我会想象这样的事情:
file >> importantInfo1;
file.skip<int>(1);
file >> importantInfo2;
或者甚至更好:
auto importantInfo1 = 0;
auto importantInfo2 = 0;
file >> importantInfo1 >> skip<int> >> importantInfo2;
我认为这样的解决方案也比在不需要时实际解析和存储值更好。
使用提供的答案制作此解决方案。它与接受的答案基本相同,但它不需要临时的。相反,它跳过第一个空格,然后跳过除空格之外的任何字符,直到再次到达空格。该解决方案可以使用2个while循环,但不需要知道提取的类型。我不是说这是一个高性能的解决方案或任何花哨的东西,但它使得生成的代码更短,更清晰,更具表现力。
template<typename CharT, typename Traits>
inline std::basic_istream<CharT, Traits>& skip(std::basic_istream<CharT, Traits>& stream)
{
while (stream && std::isspace(stream.peek())) stream.ignore();
while (stream && !std::isspace(stream.peek())) stream.ignore();
return stream;
}
答案 0 :(得分:1)
编写自己的忽略
#include <locale>
#include <iostream>
template< typename E, typename Traits, typename Pred >
std::basic_istream< E, Traits >& ignore_until( std::basic_istream< E, Traits >& in, Pred end )
{
std::basic_istream< E, Traits >::sentry ok( in );
if( ok )
{
std::ios_base::iostate state = std::ios_base::goodbit;
try
{
for( Traits::int_type m = in.rdbuf()->sgetc(); ; m = in.rdbuf()->snextc() )
{
if( Traits::eq_int_type( m, Traits::eof() ) )
{
state |= std::ios_base::eofbit;
break;
}
const E c = Traits::to_char_type( m );
if( end( c ) )
break;
}
}
catch( ... )
{
state |= std::ios_base::badbit;
if( in.exceptions() & std::ios_base::badbit )
throw;
}
in.setstate( state );
}
return in;
}
int main()
{
using namespace std;
locale loc = cin.getloc();
for( int i; ignore_until( cin, [&loc]( char c ) { return std::isspace(c,loc); } ) >> i; )
cout << i << endl;
}
答案 1 :(得分:1)
我认为你的想法是让操纵者跳过数据是正确的方法。
跳过'琐碎'的数据:
#include <sstream>
template<typename T, typename Char, typename Traits>
inline std::basic_istream<Char, Traits>& skip(std::basic_istream<Char, Traits>& stream) {
T unused;
return stream >> unused;
}
int main()
{
std::istringstream in("1 666 2 ");
int a;
int b;
in >> a >> skip<int> >> b;
std::cout << a << b << '\n';
}
如果数据变得更复杂并且构造/流变得昂贵,则必须提供专门的重载并通过char解析char以跳过它。
答案 2 :(得分:0)
如果您想在上一个示例中使用类似跳过的内容,那么您可以创建一个重载运算符&gt;&gt;的Skip类。你需要这样的东西:
class Skip {
friend istream& operator>> (istream &in, Skip &skip);
};
istream& operator>> (istream &in, Skip &skip) {
// I'm not sure why you are parameterizing skip, but this is where
// you would do whatever handles that
}