Я пишу кроссплатформенный консольный чат и у меня странная проблема:
Затем возникает проблема: символы не отображаются в терминале (как при вводе пароля — ОС получает мои символы, но не отображает их). Он показывает, когда я набираю «Enter» — все, что я ввожу, выполняет.
На сервере много потоков: основной (для отправки сообщений клиентам), для приема и для каждого подключенного клиента.
Клиент имеет 2 потока: основной (для отправки сообщений на сервер) и для получения сообщений.
Все операции получения являются асинхронными (я использую select()
метод)
Я использую следующее, чтобы получить сообщение от пользователя:
void Chat::getMessageFromUser(string &message) {
message = "";
strcpy(Chat::currentMessage, this->getMessageSigningUp().c_str());
char newChar = '\0';
int newCharPtr = this->getCurrentMessageLength();
int minLength = newCharPtr;
*this->output << Chat::currentMessage;
while ((newChar = Chat::getch()) != '\n' && newCharPtr < Chat::MESSAGE_MAX_LENGTH) {
if (newChar == 127) { //127 is code of '\b' (backspace button)
if (newCharPtr == minLength)
continue;
*this->output << "\b \b";
--newCharPtr;
continue;
}
*(Chat::currentMessage + newCharPtr) = newChar;
*this->output << newChar;
++newCharPtr;
}
Chat::currentMessage[newCharPtr] = '\0';
*this->output << endl;
message = Chat::currentMessage;
memset(Chat::currentMessage, 0, Chat::getCurrentMessageLength());
strcpy(Chat::currentMessage, this->getMessageSigningUp().c_str());
}
Я использую это для обработки следующей ситуации:
Один пользователь вводит сообщение, и в это время receiveThread
получает новое сообщение. В этом случае я помещаю новое сообщение, используя это:
void Chat::putMessageInChat(const char *message) {
for (int i = 0; i < Chat::getCurrentMessageLength(); ++i)
*this->output << "\b \b";
*this->output << message << endl;
*this->output << Chat::getCurrentMessage();
}
Метод getch () выглядит так:
int Chat::getch() {
struct termios oldt,
newt;
int ch;
tcgetattr( STDIN_FILENO, &oldt );
newt = oldt;
newt.c_lflag &= ~( ICANON | ECHO );
tcsetattr( STDIN_FILENO, TCSANOW, &newt );
ch = getchar();
tcsetattr( STDIN_FILENO, TCSANOW, &oldt );
return ch;
}
Может быть getch()
это проблема? Или мне что-то не близко? В чем проблема?
Да, следующий код в вашем getch()
Функция деактивирует прямой вывод:
newt.c_lflag &= ~( ICANON | ECHO );
tcsetattr( STDIN_FILENO, TCSANOW, &newt );
Вы удаляете ECHO
флаг. Это означает, что набранные символы больше не будут отображаться напрямую.