cosa succede quando si cin >> lettera in variabile int? Ho provato un semplice codice per aggiungere 2 numeri int, prima li ho letti, piuttosto che aggiungerli. Ma quando inserisco la lettera, fallisce e stampa tonnellate di numeri sullo schermo. Ma cosa causa questo errore? Voglio dire, mi aspettavo che caricasse e usasse il codice ASCII di quella lettera.C++ carattere per int
risposta
se si esegue il cast esplicito su un int, verrà utilizzato il codice ASCII, altrimenti non eseguirà il cast da solo su int, in modo da ottenere gli strani risultati ottenuti.
Si potrebbe utilizzare int istream::get();
io suppone che si abbia il codice come questo:
int n;
while (someCondition) {
std::cin >> n;
.....
std::cout << someOutput;
}
Quando si entra qualcosa che non può essere letta come un intero, il flusso (std :: cin) entra in un fallito stato e tutti i seguenti tentativi di input falliscono fintanto che non si ha a che fare con l'errore di input.
È possibile verificare il successo di un'operazione di input:
if (!(std::cin >> n)) //failed to read int
ed è possibile ripristinare il flusso di un buono stato ed eliminare caratteri non elaborati (l'ingresso che ha causato l'errore in ingresso):
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
Un'altra possibilità è accettare l'input in una variabile stringa (che raramente fallisce) e provare a convertire la stringa in int.
Questo è un problema molto comune con l'input e ci dovrebbero essere tonnellate di thread su di esso qui e altrove.
Grazie, quindi se ho capito bene, stdout invia effettivamente il codice ASCII al programma, ma std :: cin riconosce che tipo è e lo usa in quel modo. – Vit
Se si prevede di immettere la variabile ** int **, allora "123" è OK ma "xyz" rende l'operazione di input non riuscita. Lo stream riceve solo una sequenza di caratteri dall'input, ma esegue conversioni sul tipo richiesto e indica i fallimenti in modo tale che puoi e dovresti testare. – visitor
Il problema è che quando si legge in una variabile intera, utilizzando flussi C++, il metodo di input si aspetta caratteri che possono costituire un numero, come '+', '-', '0' ... '9 '. Qualsiasi carattere che non è in questo set termina l'input e viene creato un numero da questi caratteri.
Per ottenere il valore ASCII di un carattere, è necessario immettere i dati in una variabile char
. Internamente, ha il valore ASCII (a condizione che il programma non stia leggendo i caratteri a 16 bit o EBCDIC). Se si desidera visualizzare il valore ASCII, sarà necessario emettere la variabile char
come numero intero (in genere richiede un cast prima dell'output).
Se la lettura di un intero non riesce, il programma deve informare l'utente che l'immissione non è corretta. Il programma potrebbe richiedere che l'utente inserisca nuovamente il numero prima che il programma possa elaborare i dati di input.
Quando si sta facendo qualcosa di simile:
int x;
cin >> x;
si indica C++ per aspettare di leggere un int
da tastiera. In realtà, quando si inserisce qualcosa che non è uno int
, il flusso di input (input standard, in questo caso) rende inutilizzabile a causa del suo stato di errore.
Ecco perché personalmente preferisco sempre leggere le stringhe e convertirle in numeri se necessario. Ci sono funzioni di conversione nella parte C della libreria standard C++ che può aiutare con questo.
double cnvtToNumber(const std::string &num)
{
char * ptr;
double toret = strtod(num.c_str(), &ptr);
if (*ptr != 0) { // If it got to the end of the string, then it is correct.
throw std::runtime_error("input was not a number");
}
return toret;
}
Qui si converte un numero e si rileva se la conversione è corretta.strtod(s)
si fermerà solo quando trova la fine della stringa o uno spazio. Al fine di evitare gli spazi ingannare la funzione di uscita, si può aver bisogno di una funzione di assetto:
std::string &trim(std::string &str)
{
// Remove trailing spaces
unsigned int pos = str.length() -1;
while(str[ pos ] == ' ') {
--pos;
}
if (pos < (str.length() -1)) {
str.erase(pos + 1);
}
// Remove spaces at the beginning
pos = 0;
while(str[ pos ] == ' ') {
++pos;
}
if (pos < 1) {
str.erase(0, pos);
}
return str;
}
Ora si può tranquillamente leggere da console (o qualsiasi altro flusso di input):
int main()
{
std::string entry;
try {
std::getline(std::cin, entry);
int age = cnvtToNumber(trim(entry));
std::cout << age << std::endl;
} catch(const std::exception &e) {
std::cerr << e.what() << std::endl;
}
}
Naturalmente è possibile perdere la precisione se leggi sempre double
e poi convertirli. Esistono funzioni specifiche per i numeri interi (strtol(s)
), nel caso in cui si desideri approfondire ulteriormente.
- 1. carattere letterale in C: è un int o un carattere?
- 2. Carattere moltiplicato per intero (C++)
- 3. C++ uint, unsigned int, int
- 4. È legale questo C/C++? `Int * p = (int []) {1,2,3};`
- 5. non operatore in C++ per int?
- 6. Puntatori in C# per creare array int?
- 7. Come convertire int [] a int [,] - C#
- 8. Come convertire un carattere ASCII nel suo valore int ASCII?
- 9. Dimensioni del carattere ('a') in C/C++
- 10. C# stringa [] su int []
- 11. C Concatenate int
- 12. Perché int è piuttosto che unsigned int utilizzato per cicli C e C++?
- 13. C# int conversione byte
- 14. C++ float to int
- 15. C# immutable int
- 16. Marshalling int * a C#
- 17. C: Quale carattere deve essere usato per ptrdiff_t in printf?
- 18. Ottieni il VK int da un carattere arbitrario in java
- 19. Moltiplicando char e int insieme in C
- 20. Sostituisci carattere "in C#
- 21. WCF - "Incontrato carattere inatteso 'c'."
- 22. C# unsigned int valore predefinito
- 23. C++ ottenere ogni cifra int
- 24. C# Enum o costanti int
- 25. C++ int alla conversione stringa
- 26. foreach in C++ int array
- 27. Provare a convertire un int [] in int [,] utilizzando C#
- 28. Differenza tra int fpurge() e int fflush() in C
- 29. cosa fa int() in C++?
- 30. C# int a Flag Enum
Puoi pubblicare il codice che hai usato? –