2016-01-05 8 views
5

Sto lavorando attraverso la programmazione di Bjarne Stroustrup - Principles and Practice con C++ ed è venuto al seguente esempio:cin in C++ cercando di assegnare valori stringa a una variabile int?

#include "std_lib_facilities.h" 

int main() { 
    /* Name and Age input */ 
    cout << "Please enter your first name and age\n"; 
    string first_name = "???"; 
    int age = -1.0; 
    cin >> first_name >> age; 
    cout << "Hello," << first_name << "(age " << (age * 12) << " months)\n"; 
    return 0; 
} 

Se si esegue il programma e l'input Carlos 22, sarà trasmesso correttamente Hello, Carlos (age 22). Tuttavia, se inserisci Carlos 22, dice che l'output dovrebbe essere Hello, 22 (age -1) perché "Carlos non è un numero intero ... non verrà letto". Tuttavia, quando lo eseguo, restituisce Hello, 22 (age 0) che sembra assegnare un valore di spazzatura ad esso. Sono curioso del motivo per cui ciò sta accadendo, in quanto il libro implica che, a meno di non inserire un numero intero, non tenterà di assegnare nulla alla variabile age. Ho eseguito il codice con i punti di interruzione e confermato il valore di age modifiche da -1 a 0 una volta inserito l'input non intero.

Sto facendo qualcosa di sbagliato? O è una stranezza dovuta al fatto che lo sto costruendo attraverso Xcode e qualunque compilatore viene incluso in questo?

+0

Questo è un "comportamento non definito" che si sta ottenendo. In tali casi l'output può essere qualsiasi cosa –

+4

C++ 11 in poi imposterà i tipi scalari su 0 quando l'estrazione non riesce, prima di C++ 11 il valore non è stato toccato. – user657267

+0

@ user657267, Ah, grazie per quello. Ero confuso perché era l'edizione aggiornata del libro per C++ 11, ma dopo aver letto il tuo commento, ho guardato l'errata e abbastanza sicuro, c'era una nota su questo. Grazie! – Dan

risposta

4

Se si segue la traccia delle chiamate dalla chiamata

cin >> age; 

si finisce con una chiamata a std::strtol. Il valore di ritorno di strtol è:

  • Se la conversione non può essere eseguita, viene restituito 0.

Controllare lo stato del cin dopo le chiamate per assicurarsi che tutte le estrazioni hanno avuto successo.

cin >> first_name >> age; 
if (cin) 
{ 
    // Extraction was successful. 
    // Use the data. 
} 
else 
{ 
    // Extraction was not successful. 
    // Deal with the error. 
} 
+1

Ah, questo ha senso. Ho appena cercato l'errata del libro e ho trovato questo: "Questo non è veramente un errata, ma alcune implementazioni azzerano un int quando >> fallisce. Alla fine lo faranno tutte, ma fino a quando C++ 11 non lo ha fatto. ottieni 0 o -1 in base alla vendemmia della tua implementazione. " Quindi, come hai sottolineato, sta implementando gli standard come dovrebbe. Grazie! – Dan

+1

@Dan, è un peccato che i libri, anche quelli del padre della lingua, diventino obsoleti non prima di troppo. –

Problemi correlati