我如何 return 标准输入到控制台?
How can I return stdin to the console?
我可能在这里遗漏了一些东西,但是否可以将 stdin
更改为文件指针,然后将其切换回控制台?
示例:
stdin = fp;
for (int x; x < 10; x++)
{
c = getchar()
}
stdin = ??? // Return the stream to the console
先保存在另一个变量中
FILE *save_stdin = stdin;
stdin = fp;
...
stdin = save_stdin;
当然第一种情况可能不需要改stdin
。您可以只使用 getc(fp)
而不是 getchar()
。仅当您调用使用 stdin
且无法更改的代码时才需要重新分配 stdin
。
根据 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.
所以,这样做是不安全的。
但是,您可以使用带有输入流文件描述符和读取模式的 fdopen 来恢复标准输入,如下所示:
stdin = fdopen(0, "r");
在下面的代码中,第一个循环从文件example中读取数据,第二个循环从标准输入中读取字符:
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;
“官方”答案是freopen()
。理论上可以调用
freopen("somefile", "r", stdin);
现在 stdin
正在读取 "somefile"
。但是,一旦完成此操作,完成后要让 stdin
返回标准输入(或者,如您所说的“控制台”)将变得棘手或不可能。另见问题 12.33 and 12.34 in the old C FAQ list.
但实际上:您为什么要尝试以这种方式重新分配 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);
}
我可能在这里遗漏了一些东西,但是否可以将 stdin
更改为文件指针,然后将其切换回控制台?
示例:
stdin = fp;
for (int x; x < 10; x++)
{
c = getchar()
}
stdin = ??? // Return the stream to the console
先保存在另一个变量中
FILE *save_stdin = stdin;
stdin = fp;
...
stdin = save_stdin;
当然第一种情况可能不需要改stdin
。您可以只使用 getc(fp)
而不是 getchar()
。仅当您调用使用 stdin
且无法更改的代码时才需要重新分配 stdin
。
根据 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.
所以,这样做是不安全的。 但是,您可以使用带有输入流文件描述符和读取模式的 fdopen 来恢复标准输入,如下所示:
stdin = fdopen(0, "r");
在下面的代码中,第一个循环从文件example中读取数据,第二个循环从标准输入中读取字符:
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;
“官方”答案是freopen()
。理论上可以调用
freopen("somefile", "r", stdin);
现在 stdin
正在读取 "somefile"
。但是,一旦完成此操作,完成后要让 stdin
返回标准输入(或者,如您所说的“控制台”)将变得棘手或不可能。另见问题 12.33 and 12.34 in the old C FAQ list.
但实际上:您为什么要尝试以这种方式重新分配 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);
}