a_coder
a_coder

Reputation: 90

How can I return stdin to the console?

I may be missing something here, but is it possible to change stdin to be a file pointer and then switch it back to the console?

Example:

stdin = fp;
for (int x; x < 10; x++)
{
   c = getchar()
}
stdin = ??? // Return the stream to the console

Upvotes: 1

Views: 1276

Answers (3)

Steve Summit
Steve Summit

Reputation: 47952

The "official" answer is freopen(). Theoretically you can call

freopen("somefile", "r", stdin);

and now stdin is reading from "somefile". However, once you've done this it's either tricky or impossible to get stdin pointing back at standard input (or, as you called it, "the console") when you're done. See also questions 12.33 and 12.34 in the old C FAQ list.

But really: why are you trying to reassign stdin in this way? stdin is basically a global variable, and any time you have the pattern

change global variable;
make function call that implicitly uses global variable;
set global variable back to what it was;

you have poor design and a recipe for disaster. Usually what you want to do is to create a modified version of that function call in the middle -- whatever it is -- that lets you pass the something in as an explicit parameter, rather than implicitly using the global variable.

In this case, you don't even need to invent anything new, because instead of getchar() which implicitly reads from the global stdin, you can just call getc(fp), which reads from whatever file pointer you want to specify:

for (int x; x < 10; x++)
{
   c = getc(fp);
}

Upvotes: 4

BlueDiary9
BlueDiary9

Reputation: 105

According to the man stdin:

Since the symbols stdin, stdout, and stderr are specified to be macros, assigning to them is nonportable. The standard streams can be made to refer to different files with help of the library function freopen, specially introduced to make it possible to reassign stdin, stdout, and stderr.

So, it is not safe to do that. But, you can use fdopen with input stream file descriptor and reading mode to recover stdin as following:

stdin = fdopen(0, "r");

In the following code, the first loop reads the data from the file example, and the second loop reads characters from the standard input:

FILE *fp = fopen("example.txt", "r");

char c;
stdin = fp;
while ((c = fgetc(stdin)) != EOF) {
    printf("%c", c);
}    

stdin = fdopen(0, "r");
while ((c = fgetc(stdin)) != EOF) {
    printf("%c", c);
}

fclose(fp);
return 0;

Upvotes: -1

Barmar
Barmar

Reputation: 781058

Save it in another variable first.

FILE *save_stdin = stdin;
stdin = fp;
...
stdin = save_stdin;

Of course, there may be no need to change stdin in the first case. You could just use getc(fp) instead of getchar(). Reassigning stdin would only be necessary if you're calling code that uses stdin and can't be changed.

Upvotes: -1

Related Questions