我一直在尝试从用户输入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;
}
我得到以下输出:
如果我输入的字符超过8个,它将自动为我的file_path
分配8个字符以上的字符。它不要求第二个输入!
PS:我尝试使用scanf("%8s", password)
而不是fgets。同样的问题。
请帮助,谢谢
答案 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()
的呼叫本身并不那么安全,因为在返回时未指定它们“隐藏其足迹”。这是除了本文之外更深层次的主题。