I want to read exactly N bytes from stdin or a file multiple times, then read less than N bytes once and then read EOF. I expected this to work:
char s[5] = "11111";
while (scanf("%4c", s) != EOF) {
printf("%s", s);
}
However, when I type 1234567890
, it prints 1234156781
. This is because with c
type modifier it doesn't put \0
after read chars.
Other things I tried:
"%4s"
reads until first whitespace"%4[^\n]"
and fgets
do read until first end of line"%4[^\0]"
doesn't work (why?)"%4[]"
doesn't work"%4"
doesn't workIs there a way to scanf up to N characters including spaces and new lines, and store them as a zero-terminated string
No, not with a single scanf()
call.
The below comes close, except it does not consume the '\n'
, nor does it assign anything (including a null character) to buff[]
when the first character is '\n'
.
#define N 100
char buf[N+1];
if (scan("%100[^\n]", buf) == 1) {
"%4[^\0]" doesn't work (why?)
scanf("%4[^\0]", s)
is like scanf("%4[^", s)
.
Both are UB because the format "%4[^"
is invalid. The format parsing stops at the first null character.
Perhaps something pathologic like scanf("%4[\001-\377]", s)
will "work", yet scanf()
is just not the right solution for this task.
fgets()
readily reads 1 line, including the '\n'
.
#define N 100
char buf[N+1];
if (fgets(buf, sizeof buf, stdin)) {
...
@Timofey X How does fgets()
not meet the function needs?
If OP wants to read past '\n'
, then use fread()
.
#define N 100
char buf[N+1];
size_t len = fread(buf, 1, N, stdin);
buf[len] = 0;