C语言 如何将stdin返回到控制台?



我可能在这里缺少一些东西,但是有可能将stdin更改为文件指针,然后将其切换回控制台吗?

的例子:

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

官方;答案是freopen()。理论上你可以调用

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

,现在stdin"somefile"读取。然而,一旦你做到了这一点,让stdin指向标准输入(或者,正如你所说的,"控制台")就变得棘手或不可能了。参见旧C常见问题列表中的问题12.33和12.34。

但是真的:为什么你要用这种方式重新分配stdin?stdin基本上是一个全局变量,当你使用

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

你有一个糟糕的设计和一个灾难的配方。通常你想做的是在中间创建一个修改版本的函数调用——不管它是什么——让你把中的东西作为显式参数传递,而不是隐式地使用全局变量。

在这种情况下,您甚至不需要发明任何新的东西,因为您可以调用getc(fp),而不是从全局stdin隐式读取getchar(),它从您想指定的任何文件指针读取:

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

先保存到另一个变量中。

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

当然,在第一种情况下可能不需要更改stdin。您可以使用getc(fp)而不是getchar()。只有当你调用使用stdin且不能更改的代码时,才需要重新分配stdin

根据man stdin:

由于符号stdin、stdout和stderr被指定为宏,对它们赋值是不可移植的。标准流可以是在库函数的帮助下引用不同的文件Freopen,是专门为重新赋值stdin而引入的,标准输出和标准输出

所以,这样做是不安全的。但是,您可以使用fdopen与输入流文件描述符和读取模式来恢复stdin,如下所示:
stdin = fdopen(0, "r");
在下面的代码中,第一个循环从文件示例中读取数据,第二个循环从标准输入中读取字符:
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;

最新更新