C-截断的char数组输入自动分配给下一个char数组

时间:2018-10-16 19:51:47

标签: c arrays char c-strings

我一直在尝试从用户输入2个char数组。

如果输入字符超过指定长度,我想截断它们。 这是我到目前为止所做的。

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;

}

我得到以下输出:

enter image description here

如果我输入的字符超过8个,它将自动为我的file_path分配8个字符以上的字符。它不要求第二个输入!

PS:我尝试使用scanf("%8s", password)而不是fgets。同样的问题。

请帮助,谢谢

1 个答案:

答案 0 :(得分:1)

在OP的代码中,不适合前fgets()的输入将保留用于后续输入。更好的代码会占用整行,并检测行是否过长。

使用fgets()和足够长的缓冲区来查找不完整的 line 输入。
再读至少2个字符:多余的字符和'\n'


也许使用您自己的my_gets()来读取一行。

// 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;
}

应用

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;
}

从安全角度出发,最好在完成代码后清理password[]line[]

memset(password, 0, sizeof password);

然而,对fgets(), fgetc()的呼叫本身并不那么安全,因为在返回时未指定它们“隐藏其足迹”。这是除了本文之外更深层次的主题。