I'm writing a cross-platform console chat and having a strange problem:
Then comes the problem: the characters not displaying in terminal (as when you enter the password - OS gets my characters, but doesn't display it). It show when I type 'Enter' - all what I enter executing.
The server has a lot of threads: main (for sending messages to clients), for accepting and for each client connected.
The client has 2 threads: main (for sending messages to server) and for receiving messages.
All receive operations are asynchronous (I use select()
method)
I'm using the following to get a message from user:
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());
}
I use it for processing next situation:
One user enters the message, and in this time receiveThread
gets new message. In this case I put new message using this:
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() method looks like:
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;
}
May be getch()
is problem? Or I'm not close something? What's the problem?
Yes, the following code in your getch()
function deactivates the direct output:
newt.c_lflag &= ~( ICANON | ECHO );
tcsetattr( STDIN_FILENO, TCSANOW, &newt );
You are removing the ECHO
flag. This means that characters that are typed will no longer be shown directly.