简体   繁体   中英

C - Truncated char array input automatically assigned to next char array

I've been trying to input 2 char arrays from user.

I want to truncate the input characters if they are more than specified length. This is what I have done so far.

int main(){

    printf("Enter Password: ");
    char password[9]= {0};
    fgets(password, sizeof(password), stdin);


    printf("Enter key file path: ");
    char file_path[200];
    fflush(stdin);
    fgets(file_path, sizeof(file_path), stdin);
    puts(file_path);

    return 0;

}

I get this output:

在此处输入图片说明

If I enter more than 8 chars, it automatically assigns charcaters above 8 to my file_path . It does not ask for the 2nd input!

PS: I tried scanf("%8s", password) instead of fgets. Same issue.

Please Help, Thanks

In OP's code, the input that does not fit in the first fgets() remains for subsequent input. Better code would consume the entire line and detect if the line is excessively long.

Use fgets() with a long enough buffer to look for incomplete line input.
Read at least 2 more characters: extra character and '\\n' .


Perhaps use your own my_gets() to read a line.

// Read a line
// If input, without the \n fits in the destination, return `s`
// else return NULL
// Conditions: line != NULL,  0 < sz <= INT_MAX
char *my_gets(char *line, size_t sz) {
  if (fgets(line, (int) sz, stdin) == NULL) {
    line[0] = '\0';
    return NULL; // EOF
  }

  size_t length = strlen(line);
  if (length > 0 && line[length - 1] == '\n') {
    line[--length] = '\0';  // Chop off \n
  } else if (length == sz - 1) {
    // Consume rest of line
    bool looped = false;
    int ch;
    while ((ch = fgetc(stdin)) != '\n' && ch != EOF) {
      looped = true;
    }
    if (looped) {
      return NULL; // Line too long
    }
  }
  return line;
}

Application

int main(void) {
    printf("Enter Password: ");
    char password[9];
    if (my_gets(password, sizeof password) == NULL) {
      return EXIT_FAILURE; 
    }
    puts(password);

    printf("Enter key file path: ");
    char file_path[200];
    if (my_gets(file_path, sizeof file_path) == NULL) {
      return EXIT_FAILURE; 
    }
    puts(file_path);

    return EXIT_SUCCESS;
}

From a security standpoint, good to scrub password[] and line[] after code is done with it.

memset(password, 0, sizeof password);

Yet the call to fgets(), fgetc() are themselves not so secure as they are not specified to "cover their tracks" as they return. This is a deeper subject beyond this post.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM