可以创建一个代码来识别文件是否像以下一样传递:
program.out < file.dat
我为此搜索答案,因为我想编写代码来执行以下操作:
int main (int argc, char *argv[])
{
char filename[50];
if ( argc > 1 )
{
strcpy (filename, argv[1]);
}
else if ( SOMETHING )
{
/* copy the stdin into fin (?) */
}
FILE *fin;
fin = fopen (filename, "r");
/* ... */
fclose(fin);
}
return 0;
}
如果文件以SOMETHING
传递,<
评估为1,否则为0。
如果可能的话,我正在寻找一种使用标准C的解决方案。
答案 0 :(得分:3)
我们无法在ISO C中检测到这一点(也就是说,不使用平台扩展,例如在POSIX上使用fileno
获取文件描述符,然后通过获取fstat
的属性来对其运行一些测试,等等。)
如果ISO C连接到交互式设备,则{C}需要stdin
流进行行缓冲。然而,这对我们没有帮助,因为没有便携式函数来查询FILE *
的缓冲模式:只有“setter”,没有“getters”。 GNU C库有一个__flbf (FILE *stream)
,用于报告流是否是行缓冲的,但它是一个明显的扩展,在<stdio_ext.h>
标头中声明。
如果您的程序必须使用文件,而不是使用交互式设备的标准输入,那么一个好的解决方案是强制执行程序的参数。使它需要一个文件名参数,并始终打开该文件。然后你确定你有这个文件。
您还可以使参数可选,如果缺少,则打开默认文件,忽略stdin
。
您还可以使用freopen
使stdin
指向文件。然后隐式使用stdin
的代码将从该文件中获取输入:
的伪代码:
name = "some default"
if we have an argument
name = that argument
if (freopen(name, mode, stdin) == 0)
handle error
else
stdin is now a file; process it
如果你真的必须支持program < file
情况,同时将program
情况(交互式输入)标记为无效,则需要上述特定于平台的黑客攻击。
答案 1 :(得分:2)
如果您使用特定于Unix的解决方案,则可以使用isatty()
:
FILE *fin;
int need_to_close;
if (isatty(fileno(STDIN))) { // I/O not redirected
fin = fopen("file.dat", "r");
need_to_close = 1;
} else {
fin = stdin;
need_to_close = 0;
}
/* ... */
if (need_to_close) {
fclose(fin);
}
答案 2 :(得分:0)
可能this answer可以提供帮助: 它说,
在Posix系统上,您可以测试cin是否来自a 终端或使用isatty
重定向
#include <unistd.h>
if (isatty(STDIN_FILENO)) {
// not redirected
} else {
// redirected
}