Моя проблема:
Моя цель - прочитать строку фиксированной длины из stdin
, сохранить ее в буфере и сразу же продолжить выполнение следующего кода, но ни fgets()
, ни scanf()
перестать ждать получения большего ввода, даже если фиксированное количество символов для чтения фиксировано -> scanf("%5s",c);
и fgets(b,6,stdin);
.
Я написал этот пример, чтобы проиллюстрировать проблему:
#include <stdio.h>
#include <string.h>
int main(void)
{
char b[6];
char c[6];
printf("Enter a string of 5 characters (b):\n");
fgets(b, sizeof(b), stdin);
getchar(); // catch the left newline in stdin because in
// b was not enough space.
printf("\nEnter a string of 5 characters (c):\n");
scanf("%5s", c);
//getchar(); // catch the left newline. important if there is any
// read operation thereafter.
printf("\nb: %s\n", b);
printf("c: %s\n", c);
return 0;
}
Выполнение:
/a.out
Enter a string of 5 characters (b):
hello
Enter a string of 5 characters (c):
world
b: hello
c: world
Оба, fgets()
и scanf()
, ждут перехода на новую строку. В качестве примечания: в случае scanf()
с указателем формата %s
любой пробел остановит использование директивы; В случае scanf()
с указателем формата %[
и отрицательным набором сканирования %[^N]
вхождение N
остановит потребление.
В любом случае он ожидает большего ввода, хотя и указан для чтения всего 5 символов.
Как прочитать строку, не ожидая ввода большего числа?
Мои исследования:
Я нашел способ достичь того, что я хочу, но это довольно большой обходной путь: я мог бы поймать каждый символ отдельно и использовать производную getch()
для Linux (потому что я работаю с Linux и conio.h здесь не topi c), которые предоставляются в ответах на Что эквивалентно getch () & getche () в Linux? в for
-l oop и после этого присваивает завершающий нулевой символ последнему элементу, например, fe :
#include <termios.h>
#include <stdio.h>
static struct termios old, current;
/* Initialize new terminal i/o settings */
void initTermios(int echo)
{
tcgetattr(0, &old); /* grab old terminal i/o settings */
current = old; /* make new settings same as old settings */
current.c_lflag &= ~ICANON; /* disable buffered i/o */
if (echo) {
current.c_lflag |= ECHO; /* set echo mode */
} else {
current.c_lflag &= ~ECHO; /* set no echo mode */
}
tcsetattr(0, TCSANOW, ¤t); /* use these new terminal i/o settings now */
}
/* Restore old terminal i/o settings */
void resetTermios(void)
{
tcsetattr(0, TCSANOW, &old);
}
/* Read 1 character - echo defines echo mode */
char getch_(int echo)
{
char ch;
initTermios(echo);
ch = getchar();
resetTermios();
return ch;
}
/* Read 1 character without echo */
char getch(void)
{
return getch_(0);
}
/* Read 1 character with echo */
char getche(void)
{
return getch_(1);
}
int main(void)
{
char b[6];
int c;
printf("Enter a string of 5 characters (b):\n");
for(int i = 0; i < 5; i++)
{
if((c = getch_(1)) == EOF)
{
if(ferror(stdin))
{
}
else if(feof(stdin))
{
fprintf(stderr,"End of file reached!");
}
}
else
{
b[i] = c;
}
}
b[5] = '\0';
printf("\n\n");
puts(b);
return 0;
}
Но этот метод довольно большой обходной путь. Есть ли способ добиться этого более простым способом?