Проблема с вашим кодом в том, что fgets берет первые 8 символов с входа и игнорирует остальные. Очевидно, что если вы приглашаете пароль, вы не хотите игнорировать любой ввод! Возможно, вы захотите сделать что-то более причудливое, чтобы убедиться, что вы захватили весь ввод.
Мои первые две попытки ответить на этот вопрос были неверными. Спасибо Wildplasser за то, что я держал ноги у огня.
Итак, хакерский ответ: используйте действительно большой буфер. fgets - это, вероятно, ваше простое решение.
В качестве альтернативы, вы можете динамически распределять память, когда входная строка превышает ваш буфер.
Но, просто для удовольствия, вот реализация, которая выводит нас из ловушки "строкового буфера", в которой я не знал, что getchar был.
Для этого я использовал очень красивый комментарий: getchar () и stdin
PS: Хорошо, хорошо, я протестировал на этот раз. Оно работает. На моем Mac.
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <termios.h>
int main(void)
{
int c, i;
char buffer[9];
struct termios tty_opts_default, tty_opts_raw;
if (!isatty(STDIN_FILENO)) {
printf("Error: stdin is not a TTY\n");
return 1;
}
/* save tty settings for later. */
tcgetattr(STDIN_FILENO, &tty_opts_default);
/* put tty settings into raw mode. */
cfmakeraw(&tty_opts_raw);
tcsetattr(STDIN_FILENO, TCSANOW, &tty_opts_raw);
/* NOW we can grab the input one character at a time. */
c = getchar();
while (i < 8 && c != EOF && c != '\n' && c != '\r') {
/* Since we are collecting a pwd, we might want to enforce other
password logic here, such as no control characters! */
putchar('*');
buffer[i++] = c;
c = getchar();
}
buffer[i] = '\0';
/* Restore default TTY settings */
tcsetattr(STDIN_FILENO, TCSANOW, &tty_opts_default);
/* Report results to user. */
printf("\nPassword received.\n");
printf("(It was '%s' -- don't tell anyone! Quick! Hide the terminal!)\n", buffer);
return 0;
}