2013-09-28 28 views
6

Z scanf jednym wolno pominąć dopasowane tokeny, po prostu dodając * do wzoru, jak w:Ignorując/pomijanie znaków za pomocą std :: cin

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

Czy istnieje odpowiednik podejście z std::cin? Coś podobnego (oczywiście, oszczędzając użycie dodatkowych zmiennych):

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

Odpowiedz

3

To nie jest proste zadanie dla strumieni wejściowych w C++, aby zrobić to samo. Funkcja scanf otrzymuje oczekiwany format: "%d %*s %d" i może patrzeć w przyszłość, aby ustalić, co się dzieje. Z kolei operator >> próbuje usatysfakcjonować bieżący parametr wejściowy.


Masz szanse na napisanie własnego manipulatora istream do jedzenia danych wejściowych, aż do osiągnięcia cyfry.

Spróbuj mój kod naiwny:

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; 
} 

można rozszerzyć i poprawić powyższy kod, aby osiągnąć to, czego potrzebujesz.

+0

+1 Brzmi rozsądnie! ^^ A co powiesz na zestaw przeskoków, takich jak 'std :: ios :: skip :: str',' std :: ios :: skip :: dec', a nawet 'std :: ios :: skip :: any'? Zbyt brudny? (: – Rubens

+1

@Rubens: Zobacz moją zaktualizowaną odpowiedź, druga część: – deepmax

+0

Czy nie 'std :: ctype :: scan_is' to zrobię? – 0x499602D2

3

Prawdopodobnie szuka C++ String Toolkit Library.

Sprawdź to dla bardziej example

Albo można spróbować z ignore funkcji takich jak to:

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

coś takiego: -

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

a następnie użyć jak:

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

Chociaż wydaje się, że jest to jedyna dostępna opcja ze stl, spodziewałem się czegoś bardziej eleganckiego. Std :: ios :: skip :: str' i 'std :: ios :: skip :: dec', a nawet' std :: ios :: skip :: any' byłyby bardzo ładne (: – Rubens

+0

@Rubens: - Czy to teraz pomoże? –

+1

+1 Nigdy nie chciałem, żeby twój post nie pomógł! ^^ Dzięki za funkcjonalny przykład! (: – Rubens

2

można po prostu użyć obojętne zmienną

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

ale nie ma bezpośredniego odpowiednika AFAIK.

+0

Tak, właśnie dlatego wskazałem " * oczywiście, oszczędzając użycie dodatkowych varów * "Przyzwyczajałem się do pomysłu, że to jedyne rozwiązanie, tak czy inaczej \ = – Rubens

+0

@Rubens, przepraszam, ominęłem to. – john