还有什么东西来自stdin?

时间:2014-01-17 22:59:49

标签: c file stdin argv argc

可以创建一个代码来识别文件是否像以下一样传递:

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的解决方案。

3 个答案:

答案 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
}