while((c=getch())!=13)
 {                
            pass[z++]=c;
            printf("%c",'*');        
 }

I used this while loop to take the input of the password. Everything works fine until no "wrong" key is pressed.
the problem is, suppose, if i press a wrong key n i want to delete it (backspace) then even backspace is taken as a character.. How to rectify the code??

Recommended Answers

All 10 Replies

Since you've sidestepped the command shell's conveniencies like being able to edit your input before sending it to the program, that functionality needs to be duplicated within your program. In this case that means recognizing and handling the any special characters that the shell normally handles for you:

#include <stdio.h>
#include <conio.h>

char *get_password(char *buf, size_t n)
{
    int done = 0;
    size_t i = 0;

    while (!done && i < n - 1) {
        int ch = getch();

        switch (ch) {
        case '\r':
            /* Convert CRLF to a newline */
            putchar('\n');
            buf[i++] = '\n';
            done = 1;
            break;
        case '\b':
            /* Roll back a previous character */
            fputs("\b \b", stdout);
            fflush(stdout);

            /* Don't underrun the buffer */
            if (i > 0)
                --i;

            break;
        default:
            putchar('*');
            buf[i++] = (char)ch;
            break;
        }
    }

    buf[i] = '\0';

    return buf;
}

int main(void)
{
    char buf[BUFSIZ] = {0};

    fputs(get_password(buf, sizeof buf), stdout);

    return 0;
}

ohh!! thanks a lot!!
This works great! but I have a few doubts.

*get_password(char *buf, size_t n)

what is size_t in this?? can't we take it as int because we are just passing the size which is an integer??

 fputs("\b \b", stdout);
fflush(stdout);
/* Don't underrun the buffer */
if (i > 0)
--i;

and could you please explain this part too??

why do we use 2 \b's in fputs statement????

what is size_t in this??

size_t is a typedef representing the type returned by the sizeof operator. It's very often used as the type for array indices because the maximum value of size_t will never be less than the potential number of indices in any array.

can't we take it as int because we are just passing the size which is an integer??

Yes, you can use int instead.

and could you please explain this part too??

When you type a backspace character, both the last actual character stored in the string and the last displayed asterisk need to be removed. fputs("\b \b", stdout) will handle the latter by first printing a backspace (which isn't destructive, it only moves the cursor), then one space character to overwrite the character being removed, and finally another backspace to place the cursor in the correct position.

Removing the last character from the string is even easier because all you need to do is decrement the index and the character will be overwritten on the next iteration. But there's one edge case where the index is already 0, and you don't want it to go negative or bad things happen.

These two tasks work together to keep both the password string and the display in sync when you type a backspace.

hmm.. understood!! thanks.. :)

Also printf() is a very expensive way to output a single character. Better to use putchar('*') because it's made specifically to output a single character.

oh yes!! I'l make the changes!
but why we don't use printf()?

but why we don't use printf()?

Allow me to make an enlightening comparison from my own stdio library. The back end to putchar() is fputc(), which totals in at 22 lines of code. fputs() is built on top of fputc() and is all of 6 lines.

The guts to printf() are pushing 1,000 lines of code.

print() is a very heavy function that does a lot of work. If all you need to do is print a string or character directly, there are simpler functions that do this without any extra rigmarole.

In slightly more detail:

putchar:

get the character parameter
output the character to the screen

printf:

get the format string
parse and analyze the string (not trivial)
find out that there's a CHAR format specifier
call the char output subfunction (as opposed to integer, float, octal, etc...)
get the character parameter
output the character to the screen

By the way, scanf() does the same stuff. Use getchar() for character input.

thanks to both of you!!
Your posts were very informative.. :)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.