Thread: Overwriting Console Output

  1. #1
    Registered User
    Join Date
    Jan 2017
    Posts
    6

    Overwriting Console Output

    Hello,
    I got a problem trying to programm under Linux. I was trying to implement a fuction that will overwrite an input sentence. The function shall overwrite the read letters by hitting the Enter Button.

    Code:
    int main(void) {
        char Password[10];
        int i=0,j;
        do{
            Password[i]=getche();
            if(Password[i]!=8) i++;         
            else{                       // special case: Backspace
                printf(" \b");          
                if(i>0) i--;
            }
        }while(Password[i-1]!=13);
        for(j=0;j<i-1;j++)printf("*"); // overwrite it with '*'
        printf("\n%s",Password);
    }
    It works fine under Windows but there is no getche() function under Linux.

    Do you know another possibility?

    With best regards

  2. #2
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,731
    This stackoverflow thread explains it quite well:
    c - What is Equivalent to getch() & getche() in Linux? - Stack Overflow

    All those magic numbers, change them to meaningful character literals. '\b' instead of 8, '\r' instead of 13.
    Why are you using "getche()"? Wouldn't "getch()" be better?
    Devoted my life to programming...

  3. #3
    Registered User
    Join Date
    Jan 2017
    Posts
    6
    I copied it to my Eclipse IDE, but it still waits for me to press Enter to continue... Do i have to link the terminos header to the linker library like math.h with a "m"?

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,169
    Post your latest code.

    > Do i have to link the terminos header to the linker library like math.h with a "m"?
    Unlikely.
    If you did need a library, you would have gotten linker errors and no program to run.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    Jan 2017
    Posts
    6
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <termios.h>
    char getch(){
        char Wahl = 0;
        struct termios old = { 0 };
    
        fflush(stdout);
        if (tcgetattr(0, &old) < 0){
            perror("tcsetattr()");
        }
        old.c_lflag &= ~ICANON; /* deactivate */
        old.c_lflag &= ~ECHO;
        old.c_cc[VMIN] = 1; /* send each byte */
        old.c_cc[VTIME] = 0;/* don't wait */
        if (tcsetattr(0, TCSANOW, &old) < 0){
            perror("tcsetattr ICANON");
        }
        if (read(0, &Wahl, 1) < 0){
            perror("read()");
        }
        old.c_lflag |= ICANON; /* activate */
        old.c_lflag |= ECHO;
        if (tcsetattr(0, TCSADRAIN, &old) < 0){
            perror("tcsetattr ~ICANON");
        }
        //printf("%c\n", Wahl);
        return Wahl;
    }
    
    int main(void) {
        char Passwort[10];
        int i=0,j;
        do{
            Passwort[i]=getch();
            printf("%c",Passwort[i]);
            if(Passwort[i]!=8) i++;     // normal input
            else{                       // Special case: Backspace
                printf("  ");          
                if(i>0) i--;
            }
        }while(Passwort[i-1]!=13);
        for(j=0;j<i-1;j++)printf("*"); // Pressing of Enter will overwrite the output
        return 0;
    }
    getch() is working now but the Problem is now. By pressing Backspace it wont delete a letter but creating a weird output on screen. Same goes with the function of Enter...

  6. #6
    Registered User
    Join Date
    Jan 2017
    Posts
    6
    Okay i got it:
    Code:
    int main(void) {
        char Passwort[10];
        int i=0,j;
        printf("Gebe das Passwort ein:\n");
        do{
            Passwort[i]=getch();
            if(Passwort[i]==10) break;
            if(Passwort[i]!=127){
                printf("%c",Passwort[i]);
                i++;                         // Normale Eingabe
            }
            else{                       // Sonderfall: Backspace
                printf("\b \b");          // Überschreibe Eingabe in Konsole
                if(i>0) i--;
            }
    
        }while(Passwort[i]!=10);
        printf("\r");
        for(j=0;j<i;j++)printf("*"); // Bei Drücken von Enter wird der vorherige Text überschrieben
    }
    Figured out the ascii symbols for Enter and backspace

  7. #7
    Registered User
    Join Date
    Jun 2015
    Posts
    1,643
    That's pretty close. You need to ignore the backspace character completely if there's no characters in the password. You need to ensure that you don't overflow the password string. You should probably print asterisks as the password is entered. And you need to zero-terminate the string.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <termios.h>
    
    void die(const char *msg) {
        perror(msg);
        exit(EXIT_FAILURE);
    }
    
    char getch() {
        char ch = 0;
        struct termios old = { 0 };
        fflush(stdout);
        if (tcgetattr(0, &old) < 0)              die("tcsetattr()");
        old.c_lflag &= ~ICANON; // deactivate
        old.c_lflag &= ~ECHO;
        old.c_cc[VMIN] = 1;     // send each byte
        old.c_cc[VTIME] = 0;    // don't wait
        if (tcsetattr(0, TCSANOW, &old) < 0)     die("tcsetattr ICANON");
        if (read(0, &ch, 1) < 0)                 die("read()");
        old.c_lflag |= ICANON;  // activate
        old.c_lflag |= ECHO;
        if (tcsetattr(0, TCSADRAIN, &old) < 0)   die("tcsetattr ~ICANON");
        return ch;
    }
    
    int main(void) {
        enum { ENTER = 10, BACKSPACE = 127 };
        char pass[20];
        int i = 0;
    
        printf("Enter your password:\n");
    
        while (i < (int)sizeof pass - 1) {
            char ch = getch();
            if (ch == ENTER) break;
            if (ch != BACKSPACE) {
                putchar('*');
                pass[i++] = ch;
            }
            else if (i > 0) {
                printf("\b \b");
                i--;
            }
        }
        pass[i] = '\0';
    
        printf("\npass: %s\n", pass);
    
        return 0;
    }

  8. #8
    Registered User
    Join Date
    Jan 2017
    Posts
    6
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <termios.h>
    
    void die(const char *msg) {
        perror(msg);
        exit(EXIT_FAILURE);
    }
    
    char getch() {
        char ch = 0;
        struct termios old = { 0 };
        fflush(stdout);
        if (tcgetattr(0, &old) < 0)              die("tcsetattr()");
        old.c_lflag &= ~ICANON; // deactivate
        old.c_lflag &= ~ECHO;
        old.c_cc[VMIN] = 1;     // send each byte
        old.c_cc[VTIME] = 0;    // don't wait
        if (tcsetattr(0, TCSANOW, &old) < 0)     die("tcsetattr ICANON");
        if (read(0, &ch, 1) < 0)                 die("read()");
        old.c_lflag |= ICANON;  // activate
        old.c_lflag |= ECHO;
        if (tcsetattr(0, TCSADRAIN, &old) < 0)   die("tcsetattr ~ICANON");
        return ch;
    }
    
    int main(void) {
        enum { ENTER = 10, BACKSPACE = 127 };
        char pass[20];
        int i = 0, j;
    
        printf("Enter your password:\n");
    
        while (i < (int)sizeof pass - 1) {
            char ch = getch();
            if (ch == ENTER) break;
            if (ch != BACKSPACE) {
                putchar(ch);
                pass[i++] = ch;
            }
            else if (i > 0) {
                printf("\b \b");
                i--;
            }
        }
        pass[i] = '\0';
        printf("\r");
        for(j=0;j<strlen(pass);j++)printf("*");
        printf("\n");
    
        return 0;
    }
    Thanks alot! But my plan was to show the input password on screen till you press Enter. Not the other way around
    So the code above is now the right one.

  9. #9
    Registered User
    Join Date
    Jun 2015
    Posts
    1,643
    Quote Originally Posted by dani2304 View Post
    But my plan was to show the input password on screen till you press Enter. Not the other way around
    Obviously I only displayed the password for debugging purposes.
    Only an idiot would display a password!

  10. #10
    Registered User
    Join Date
    Jan 2017
    Posts
    6
    Yeah that would be weird

    But maybe you can help me with another little problem.
    Code:
    #include <stdint.h>
    #include <stdio.h>
    #include <string.h>
    #include <time.h>
    void Zeitmessung(){
        printf(" Wrong Login data for the third time in a row. 200 seconds time-out!");
        clock_t start,end;
        double duration=0;
        start=clock();
        for(;;){
            end=clock();
            duration= (double)((end - start) / CLOCKS_PER_SEC);
            if(duration>=200) break;
        }
        return;
    }
    
    int main(){
    Zeitmessung();
    }
    Working with linux the Output of the printf() command is also delayed by the duration. But shouldnt it print out first and then go to the infinite loop?
    At Windows it does excatally what i want it to do...

  11. #11
    Registered User
    Join Date
    Jun 2011
    Posts
    4,508
    You need to flush the output. Either end your print statement with a newline, or follow it with fflush(stdout).

  12. #12

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. tabular console output
    By pheres in forum C++ Programming
    Replies: 1
    Last Post: 11-05-2008, 07:02 AM
  2. How to get the console output
    By outlawbt in forum Windows Programming
    Replies: 2
    Last Post: 03-19-2008, 02:25 PM
  3. How to hide output in a console
    By thelimpkid in forum C++ Programming
    Replies: 6
    Last Post: 09-02-2007, 07:50 AM
  4. Help with Console output
    By JeremyCAFE in forum C++ Programming
    Replies: 4
    Last Post: 12-20-2005, 10:36 AM
  5. Non-Blocking-Input And Overwriting-Output
    By Geolingo in forum C++ Programming
    Replies: 3
    Last Post: 10-28-2003, 05:47 PM

Tags for this Thread