我可能在这里缺少一些东西,但是有可能将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
:
所以,这样做是不安全的。但是,您可以使用fdopen与输入流文件描述符和读取模式来恢复stdin,如下所示:由于符号stdin、stdout和stderr被指定为宏,对它们赋值是不可移植的。标准流可以是在库函数的帮助下引用不同的文件Freopen,是专门为重新赋值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;