2013-09-28 191 views
6

随着scanf一个被允许跳过匹配令牌,简单地增加*到图案,如在:忽略/跳过令牌:: CIN

int first, second; 
scanf("%d %*s %d", &first, &second); 

是否与std::cin任何等效方法?喜欢的东西(当然,节约其他变量的使用):

int first, second; 
std::cin >> first >> `std::skip` >> second; 

回答

3

对于C++中的输入流来说,做同样的事情并不是一项简单的任务。函数scanf获取所有预期格式:"%d %*s %d",并可以展望未来以确定发生了什么。

另一方面,运营商>>只是试图满足当前的入口参数。


你有机会写你自己的istream机械手吃输入,直到达到一个数字。

试试这个我天真代码:

template<typename C, typename T> 
basic_istream<C, T>& 
eat_until_digit(basic_istream<C, T>& in) 
{ 
    const ctype<C>& ct = use_facet <ctype<C>> (in.getloc()); 

    basic_streambuf<C, T>* sb = in.rdbuf(); 

    int c = sb->sgetc(); 
    while (c != T::eof() && !ct.is(ctype_base::digit, c)) 
     c = sb->snextc(); 

    if (c == T::eof()) 
     in.setstate(ios_base::eofbit); 

    return in; 
} 

int main() 
{ 
    int first, second; 

    cin >> first >> eat_until_digit >> second; 

    cout << first << " : " << second << endl; 
} 

您可以扩展和改善上面的代码来实现你所需要的。

+0

+1听起来很合理!^^一组跳过,如'std :: ios :: skip :: str','std :: ios :: skip :: dec',甚至是'std :: ios :: skip :: any'?太脏了? (: – Rubens

+1

@Rubens:查看我更新的答案,第二部分。 – deepmax

+0

不是'std :: ctype :: scan_is'做到这一点吗? – 0x499602D2

3

您可能正在寻找C++ String Toolkit Library

检查本作更example

或者你可以用ignore功能这样的尝试:

std::cin >> val1; 
std::cin.ignore (1234, ' '); 
std::cin >> val3; 

事情是这样的: -

template <class charT, class traits> 
inline std::basic_istream<charT, traits> & 
ignoreToken (std::basic_istream<charT, traits> &strm) 
{ 
    strm.ignore (1234, ' '); 
    return strm; 
} 

然后使用类似:

cin >> val1 >> ignoreToken >> val3 >> ignoreToken >> val5; 
+0

尽管它似乎是stl的唯一可用选项,但我期待着一些更整洁的东西。一个'std :: ios :: skip :: str'和'std :: ios :: skip :: dec'甚至是'std :: ios :: skip :: any'都会非常好(: – Rubens

+0

@Rubens: - 现在有帮助吗? –

+1

+1我从来没有意味着你的帖子没有帮助!^^感谢功能的例子!(: – Rubens

2

您可以简单地用一个虚拟变量

int first, second; 
std::string dummy; 
cin >> first >> dummy >> second; 

但没有直接等效AFAIK。

+0

是的,这就是为什么我指出“ *当然,不要使用额外的变量*“我已经习惯了这是唯一的解决方案的想法,无论如何\ = – Rubens

+0

@Rubens,对不起错过了这个 – john