2015-08-19 1 views
1

J'écris un simple client de messagerie instantanée dans c. Cela fonctionne actuellement bien, cependant si un utilisateur tape et reçoit un message en tapant, le message affiche AFTER le texte, alors l'utilisateur continue sur la ligne ci-dessous. Il ressemblerait à ceci:Comment conserver STDIN en bas du terminal dans C

UTILISATEUR: Je suis en train de ty ... AMI: Bonjour

pe un message. < --- (la fin des utilisateurs un message)

Mon idée est:

forcer une certaine façon les données actuelles de stdin et le charger dans un tampon, puis utilisez un \ r avant d'imprimer AMI: à effacer ce qui est sur la ligne, puis imprimer à partir du tampon. Quelqu'un at-il des exemples concrets de la façon d'accomplir cette tâche?

Le résultat final devrait être

AMI: Bonjour

UTILISATEUR: Je suis en train de taper un message

L'utilisateur a commencé à taper le message, a reçu un message, le stdin ligne a été décalée vers le bas, puis l'utilisateur a terminé leur message.

Note: Je suis sous GNOME Terminal 3.6.2 sur la dernière version de Linux Mint

+4

Vous pouvez en savoir plus sur [la bibliothèque ncurses] (https: //en.wikipedia. org/wiki/Ncurses), ou sur l'utilisation de [codes de contrôle VT100] (http://www.termsys.demon.co.uk/vtansi.htm) pour placer le curseur sur la position. –

+1

Il n'y a aucun moyen de faire cela avec le standard pur C. C ne reconnaît même pas la présence d'un terminal ou même d'un écran d'ordinateur: il ne concerne que les flux d'entrée et de sortie. – Lundin

Répondre

1

La manière habituelle de faire est d'utiliser ncurses (toute la saveur des malédictions travaillerait), en acceptant l'entrée dans une fenêtre et en écrivant le résultat à un autre. Voici un court exemple:

#include <curses.h> 

int 
main(void) 
{ 
    bool done = FALSE; 
    WINDOW *input, *output; 
    char buffer[1024]; 

    initscr(); 
    cbreak(); 
    echo(); 
    input = newwin(1, COLS, LINES - 1, 0); 
    output = newwin(LINES - 1, COLS, 0, 0); 
    wmove(output, LINES - 2, 0); /* start at the bottom */ 
    scrollok(output, TRUE); 
    while (!done) { 
    mvwprintw(input, 0, 0, "> "); 
    if (wgetnstr(input, buffer, COLS - 4) != OK) { 
     break; 
    } 
    werase(input); 
    waddch(output, '\n'); /* result from wgetnstr has no newline */ 
    waddstr(output, buffer); 
    wrefresh(output); 
    done = (*buffer == 4); /* quit on control-D */ 
    } 
    endwin(); 
    return 0; 
} 

Si vous voulez en savoir plus sur les codes de contrôle VT100 (par opposition à ECMA-48), a vt100.net manuels pour certains terminaux.

En ce qui concerne le lien VT100 control codes: qui est une source de désinformation, comme il est indiqué dans la FAQ ncurses How do I get color with VT100?