Faruk D
Faruk D

Reputation: 43

Usage of printf and fgets together in a loop

I am trying to implement a simple program which infinitely reads input from the user and then prints it. But there are some problems. It is a simple issue but my Google searches didn't lead me any solution. Here is the code.

int main() {

    char pass[32];
    int x=10;

    while (x!=0) {


        printf("\nInput the password: ");
        fgets(pass, sizeof(pass), stdin);

        printf("that is what i read: %s", pass);
    }
    return 0;
}

When I enter a string longer than 32 characters, it behaves anormally.

Input the password: pass
that is what i read: pass

Input the password: passsssss
that is what i read: passsssss

Input the password: passssssssssssssssssssssssssssssss
that is what i read: passsssssssssssssssssssssssssss
Input the password: that is what i read: sss

Input the password:

You see in the third attempt, it prints the third line automatically. I didn't type the input 'that is what i read: sss'.

Why does that happen?

Upvotes: 1

Views: 221

Answers (3)

chux
chux

Reputation: 154572

fgets() does not limit the length of a line a user enters. fgets() limits how much of that line is read.

With too much input, the remainder is left for the next input operation.


If input via fgets()lacks a '\n', then either

  • Entire line was not read, (common enough)
  • Input w/o '\n' and then end-of-file, (seldom)
  • A null character was read. (rare)
  • Input buffer smaller than 1. (pathological)

Below readily IDs the first 2.

// Test if anything was read.
if (fgets(pass, sizeof pass, stdin)) {
  // Was it missing a '\n'?
  if (strchr(pass, '\n') == NULL) {
    // Read rest of line and throw it away
    int ch;
    while ((ch = fgetc(stdin)) != '\n' && ch != EOF) {
      ;
    }
  }
}

Upvotes: 2

isrnick
isrnick

Reputation: 736

The safe solution when using fgets would be something like this:

if (fgets(pass, sizeof(pass), stdin) != NULL){
    int len = strlen(pass);
    if (len > 0 && pass[len-1] != '\n'){
        int ch;
        while ((ch=getchar()) != '\n' && ch != EOF);
    }
}

Or this:

if (fgets(pass, sizeof(pass), stdin) != NULL){
    if (strcspn(pass, "\n") == sizeof(pass) - 1){
        int ch;
        while ((ch=getchar()) != '\n' && ch != EOF);
    }
}

You need to check if there is a new line character \n in the string, if there isn't then there is excess characters left in the stdin that must be cleared.

Upvotes: 1

Dylan Conklin
Dylan Conklin

Reputation: 73

You limited your input variable to 32 characters, so in order to stop it from doing that, simply make pass[32] bigger.

Upvotes: 0

Related Questions