In the educational console chat client in C ++ you need to simultaneously receive and send messages. But when a message is received, the typed string remains on top and is not available. Are there any termios flags or any settings to keep the input? For example, typed characters were immediately placed under the received messages along with the cursor.

  • one
    I think you need ncurse - KoVadim
  • one
    If I understand correctly, then you need to break the screen into 2 parts. In one, for example, the bottom line (s) is recruited, and all output is made to the scrollable top. If so, then the proposed @KoVadim ncurses can be tried. - avp
  • I know @KoVadim @avp ncurses , it’s quite difficult there, I tried several options, but it didn’t work out, I don’t want to spend so much time on what I’d hardly ever need. I can basically do it using Qt, but I have to go through the terminal. - Roman Markov
  • @KoVadim @avp in man cursor is somehow set at the bottom of the terminal, maybe you know how? - Roman Markov
  • No one bothers you to look at him in the sorts - they are available. nongnu.org/man-db/development.html - KoVadim 4:06 pm

1 answer 1

I solved the problem using control characters (ECMA-48 CSI-sequences, DEC-sequences) which are described in the section console_codes opennet.ru.

 printf( "%c[2J", 27 ); // очистка всего экрана fflush(stdout); // эта функция немедленной отправки символов printf( "%c[?6h", 27); // режим DECOM, для окна прокрутки fflush(stdout); printf( "%c[%d;%dr", 27, 1, 40); // установка окна прокрутки с 1 по 40 ряд fflush(stdout); printf( "%c[%d;%dH", 27, y_part_msg, 1 ); // установка курсора в область fflush(stdout); // где будут набираться сообщения 

After setting the scroll window, the cursor will be in the upper left corner, so it took a redefinition of the position.

 if (select(s+1, &readset, &writeset, NULL, &timeout) == -1) ..... if(FD_ISSET(s, &readset)) // сработал сокет, то есть пришло сообщение { nbytes = recv(s, bufrcv, sizeof(bufrcv), 0); .... // сохраняем позицию курсора, необходимо, чтобы вновь вернутья к набору // сообщения, после печати принятого printf( "%c[s", 27); fflush(stdout); // устанавливаем позицию курсора на 1 строку выше чем область печати // личных сообщений printf( "%c[%d;%dH", 27, y_part_msg-1, 1 ); //вставляем 1 строку между областями чата и печати своих сообщений printf( "%c[1L", 27); // первая изюминка //установка курсора в область печати сообщений чата и вывод сообщения printf( "%c[%d;%dH", 27, y_part_chat, 1 ); fflush(stdout); printf("%s", bufrcv); fflush(stdout); 

Here it is necessary to make a few comments. Messages are always inserted into the same line relative to the upper left corner. Overlapping of the scroll window can only be avoided. Without the insertion of a new line, this happens automatically when you send your messages, as the cursor moves down to the line. But, if the message is received from others, then there is no shift of the frame due to Enter .

 printf( "%c[%d;%dH", 27, 24, 1 ); fflush(stdout); printf("%c", '\n'); // вторая изюминка printf( "%c[u", 27); // возврат к нашему сообщению fflush(stdout); } 

without the last line feed, the frame will not move down, i.e., inserting a line will be useless. My chat position and message set area values ​​are:

 int y_part_chat = 20; int y_part_msg = 22; 

It is worth noting that this code does not take into account changes in the size of the console window, but for the training chat emulator, I think that will be enough.