Я предполагаю, что вы на самом деле хотите, чтобы вход, чтобы быть в соответствии с с возможным выходом. В противном случае решение тривиально: сначала считывать значение, а затем распечатать его, например .:
std::cout << "how old are you? ";
std::cin >> x;
std::cout << "I am " << x << " years old\n";
Работа с входом, который находится в соответствии с выходным сигналом является немного более сложным. Проблема здесь в том, что обработка консоли фактически выполняется системой, а не языком. В результате при вводе данных необходимо дождаться новой строки. Новая строка будет обрабатываться консолью и создать разрыв строки. Чтобы отключить это поведение, необходимо работать, опираясь на поведение консоли. Для этого нет стандартного C++.
Я не знаю, как иметь дело с консольными элементами управления в Windows: я в первую очередь программист UNIX. В системе UNIX вы должны использовать tcgetattr()
и tcsetattr()
, чтобы установить режим ввода неканоническим (то есть, чтобы очистить бит ICANON
). Требуемый файловый дескриптор - это просто стандартный для ввода, т. Е. 0
.
После того, как консоль использует неканонический режим, все нажатия клавиш сразу же перенаправляются в приложение, и экранное эхо не выполняется. В результате функция чтения действительно должна будет эхо-символа отдельных символов, а затем переходить к функции синтаксического анализа. Самый простой способ - создать буфер фильтра потока, который выполняет эхо-запрос для std::cin
до std::cout
при пересылке символа. Тем не менее, все это вместе - немного работы ...
При подготовке демонстрации я заметил, что мне также нужно иметь дело с эхом (чтобы избежать новой строки, когда пользователь использует клавишу ввода). Также важно сбросить флаги консоли, поскольку некоторые из них фактически остаются измененными даже после завершения программы.Реализация положить биты вместе, но по-прежнему не хватает обработки ошибок может выглядеть следующим образом:
#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";
}
}
Это не имеет большого смысла для меня. Не следует ли вам сначала * просить пользователя ввести возраст, а затем вывести 'std :: cout <<« Я «<< x <<» лет. \ N "' в целом? – 5gon12eder
Так вы пытаетесь придумать что-то вроде пробела, в который пользователь может ввести свой возраст? Если это так, к сожалению, это не так, как обычно работают текстовые системы, но я уверен, что это можно сделать с помощью [ncurses] (https://en.wikipedia.org/wiki/Ncurses), хотя это будет больше сложно. – Numeri
Способ ввода чего-либо без новой строки - отключить буферизацию потока. Но это зависит от того, какую ОС вы используете и не являетесь частью C++. Например, в Windows вы можете получить символы без повторения их на экране вообще, а затем решить, какие из них будут помещаться на экран. –