Explaining the output
The arguments to a function can be evaluated in any order that the compiler chooses.
The original code looked like this (missing printf("\n");
compared to the revised code):
printf("%c %c", getc(stdin), getc(stdin));
rewind(stdin);
printf("%c %c", getchar(), getchar());
Your 'output' in the question is extremely difficult to read and interpret. However, I'm reasonably sure that what you show consists of both your input and the program's output.
You say you type s enter twice. The output you get, copied from the question, is:
s
s
s
s
The first s
and the newline that follows are what you typed. The blank line is there because the newline was read by the getc(stdin)
that appears first in the argument list, then there's the blank from the format string, and the s
which was read by the getc(stdin)
that appears second in the argument list. Your compiler, it seems, evaluates the arguments right to left — but you should not rely on that.
Now we run into a problem; there's a newline after the second s
that isn't accounted for by the code you showed when I wrote this answer. Since then, you've added the printf("\n");
which explains the output you saw.
Putting that aside, the third s
is followed by a newline and is what you typed. And again, the blank line is from the newline and then space and s
is the rest of the output, and there's probably a newline after that too.
JFTR, when I run your code (program getc73
compiled from getc73.c
), I see:
$ getc73
s
ss
s$
$
The $
is my prompt; the first s
is what I type; then the newline, blank and s
are printed (with no newline at the end); then the second s
on the third line is my next s
and return, followed by the newline and blank s
. Since there's no newline at the end, my prompt appears immediately after the fourth s
. I hit return to print another prompt at the start of the line.
Why rewind(stdin)
is a no-op
You can't successfully execute an fseek()
call on a terminal device. They don't have any storage so you can't move around like that. The rewind()
function is effectively:
void rewind(FILE *fp)
{
fseek(fp, 0, SEEK_SET);
}
So, the rewind(stdin)
call fails to rewind, but it has no way to report that to you because it returns no value. It does no good; it doesn't do any harm either. If it had worked, you would not have needed to enter the information twice.
If the standard input had been a file instead of a terminal, then the rewind would succeed — disks are seekable.
Improved formatting
If you were on a POSIX system, I'd suggest you used a feature of POSIX printf()
that allows you to print the same argument more than once:
#include <stdio.h>
int main(void)
{
printf("[%1$c] %1$d [%2$c] %2$d\n", getc(stdin), getc(stdin));
printf("[%1$c] %1$d [%2$c] %2$d\n", getchar(), getchar());
return 0;
}
When I run that on my terminal (it's a Mac running macOS Mojave 10.14.6 using GCC 9.2.0), I get:
s
[
] 10 [s] 115
s
[
] 10 [s] 115
The lines with just the s
on them are what I typed; the other lines show that the newline is printed before the letter s
.
This probably won't work for you in VS2017 — the manual for printf()
formats on Windows strongly suggests it won't work. Your best bet, probably, is to use:
#include <stdio.h>
int main(void)
{
printf("%d %d\n", getc(stdin), getc(stdin));
printf("%d %d\n", getchar(), getchar());
return 0;
}
That generates:
s
10 115
s
10 115
Choosing a good format to show what you're seeing is an art form. Don't forget to include newlines at the end of (most) printf()
format strings. Obviously, if you're building up a line of output piecemeal, you don't want newlines at the end of intermediate formats, but the majority of printf()
statements should have a newline at the end of the format.