2013-01-15 4 views
14

Mit scanf ist es, in der Regel eine direkte Art und Weise formatierte Eingabe zu nehmen:Was ist der CIN-Analogwert der scanf-formatierten Eingabe?

1) Linie mit einer reellen Zahl größer als 0 und kleiner als 1 ist auf ‚x‘ enden, zB: 0.32432523x

scanf("0.%[0-9]x", &number); 

2) Linie stellt eine Ergänzung im Format : 30 + 28 = achtundfünfzig

scanf(":%d+%d=%99s", &number1, &number2, &total); 

Was die cin Lösung ist, nur den Ständer mit ard Bibliothek?

+2

Nirgendwo * in der Nähe von * so hübsch ... 'scanf' wirklich mächtig ist. Persönlich lese ich in eine "Zeichenfolge", greife den Zeiger über 'string :: c_str()' und dann 'scanf' es. Oder ich tokeniere es selbst aus einem 'stringstream' oder was auch immer. – paddy

+1

Für formatierte Eingaben wie diese in C++ sollten Sie etwas wie [Boost Spirit] (http://boost-spirit.com/home/) betrachten. Es mag übertrieben sein, aber es ist sauberer als direkt mit Iostreams. –

+1

scanf gewinnt den Gewinn, weil es Ihnen gleichzeitig einen Rückgabewert liefert, den Sie an einer Stelle überprüfen können, um zu überprüfen, ob alles übereinstimmt. Im Cinestream müssten Sie ein paar Dinge "manuell" überprüfen. – doug65536

Antwort

5

Verwenden Sie den Operator >>, um von cin zu lesen.

int number1, number2; 
    std::string text; 
    char plus, equals; 
    std::cin >> number1 >> plus >> number2 >> equals >> text; 
    if (!std::cin.fail() && plus == '+' && equals == '=' && !text.empty()) 
    std::cout << "matched"; 

Es ist nicht so gut wie scanf weil Sie Literale überprüfen müssten, die sich in der scanf String waren. Tun Sie es mit Streams wird fast sicher, mehr Zeilen Code als scanf.

Ich würde scanf verwenden.

+1

Verwenden Sie 'cin.fail()', nicht 'cin.bad()' oder verwenden Sie 'cin' direkt als Bedingung. –

+0

Ich habe es von schlecht() zu fehlgeschlagen() geändert. Guter Ruf. – doug65536

6

Sie können eine einfache Klasse zur Überprüfung der Eingabe erstellen.

struct confirm_input { 
    char const *str; 

    confirm_input(char const *in) : str(in) {} 

    friend std::istream &operator >> 
     (std::istream &s, confirm_input const &o) { 

     for (char const *p = o.str; * p; ++ p) { 
      if (std::isspace(* p)) { 
       std::istream::sentry k(s); // discard whitespace 
      } else if ((c = s.get()) != * p) { 
       s.setstate(std::ios::failbit); // stop extracting 
      } 
     } 
     return s; 
    } 
}; 

Nutzung:

std::cin >> x >> confirm_input(" = ") >> y; 
+0

Sehr schön. Die Idee ist sehr flexibel, man könnte auf diese Weise direkt in ein Objekt eindringen. – doug65536