В коде OP вход, который не помещается в первый fgets()
, остается для последующего ввода.Более качественный код будет занимать всю строку и обнаружит, что строка слишком длинная.
Используйте fgets()
с достаточно длинным буфером для поиска неполных строк ввода.
Прочитайте по крайней мереЕще 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()
сам по себе не так безопасен, как онне указано "скрывать свои следы" при возвращении.Это более глубокая тема, чем эта статья.