Presumo si vuole realmente l'ingresso di essere in linea con con l'uscita eventuale. In caso contrario, la soluzione è banale: prima di leggere il valore e quindi stamparlo, es .:
std::cout << "how old are you? ";
std::cin >> x;
std::cout << "I am " << x << " years old\n";
trattati i di ingresso che è in linea con l'uscita è un pò più difficile. Il problema qui è che la gestione della console viene effettivamente eseguita dal sistema e non dal linguaggio. Di conseguenza, è necessario attendere una nuova riga quando si inseriscono i dati. La nuova riga sarà gestita dalla console e creerà un'interruzione di riga. Per disabilitare questo comportamento è necessario aggirare il problema facendo affidamento sul comportamento della console. Non esiste un modo standard in C++ per farlo.
Non so come gestire i controlli della console su Windows: sono principalmente un programmatore UNIX. Su un sistema UNIX si utilizza tcgetattr()
e tcsetattr()
per impostare la modalità di input come non canonica (ad esempio, per cancellare il bit ICANON
). Il descrittore di file richiesto è semplicemente quello per l'input standard, ovvero 0
.
Una volta che la console utilizza la modalità non canonica, tutti i tasti premuti vengono immediatamente inoltrati all'applicazione e l'eco dello schermo non viene eseguita. Di conseguenza, la funzione di lettura dovrà effettivamente eseguire l'eco di singoli caratteri e quindi inoltrare a una funzione di analisi. Il modo più semplice per fare è creare un buffer del flusso di filtraggio che faccia l'eco necessario per std::cin
a std::cout
durante l'inoltro del carattere. Tuttavia, mettere tutto insieme è un po 'di lavoro ...
Durante la cottura di una demo ho notato che avevo anche bisogno di occuparmi di echo (per evitare una nuova riga quando l'utente utilizza il tasto invio). È inoltre importante ripristinare i flag della console poiché alcuni di essi rimangono effettivamente modificati anche dopo la chiusura del programma.Un'implementazione mettendo insieme i pezzi, ma ancora manca la gestione degli errori potrebbe essere la seguente:
#include <iostream>
#include <ctype.h>
#include <termios.h>
struct non_canon_buf
: std::streambuf {
char buffer;
non_canon_buf() {
termios flags = {};
tcgetattr(0, &flags);
flags.c_lflag &= ~(ICANON | ECHO);
tcsetattr(0, TCSANOW, &flags);
}
~non_canon_buf() {
termios flags = {};
tcgetattr(0, &flags);
flags.c_lflag |= ICANON | ECHO;
tcsetattr(0, TCSANOW, &flags);
}
int underflow() {
if (std::cin.get(buffer)) {
this->setg(&buffer, &buffer, &buffer + 1);
if (!std::isspace(static_cast<unsigned char>(buffer))) {
std::cout << buffer << std::flush;
}
return std::char_traits<char>::to_int_type(buffer);
}
return std::char_traits<char>::eof();
}
};
int main()
{
non_canon_buf sbuf;
std::istream in(&sbuf);
std::cout << "I am ";
int age = 0;
in >> age;
std::cout << " years old\n";
if (!in) {
std::cout << "ERROR: failed to enter a valid age!\n";
}
}
fonte
2015-12-14 23:42:13
questo non ha molto senso per me. Non dovresti * prima * chiedere all'utente di inserire l'età e poi restituire 'std :: cout <<" I am "<< x <<" anni. \ N "' nel suo insieme? – 5gon12eder
Quindi stai cercando di inventare qualcosa di simile a un vuoto in cui l'utente può inserire la loro età? Se è così, sfortunatamente, non è così che generalmente funzionano i sistemi basati su testo, ma sono sicuro che ciò potrebbe essere fatto con [ncurses] (https://en.wikipedia.org/wiki/Ncurses), anche se diventerebbe più complicato. – Numeri
Il modo per immettere qualcosa senza una nuova riga è disattivare il buffering nel flusso. Ma ciò dipende dal sistema operativo in uso e non fa parte di C++. Ad esempio in Windows è possibile ottenere caratteri senza farli echeggiare sullo schermo e poi decidere in seguito quali mettere sullo schermo. –