6
$cc a.c
$./a.out < inpfilename

我想在标准输出上打印 inpfilename。我怎么做 ?我在这里先向您的帮助表示感谢...

4

9 回答 9

10

您无法获得与输入完全相同的文件名;shell 会在不告诉你的情况下处理所有重定向的东西。

在直接< file重定向的情况下,您可以检索与 stdin 关联的文件路径,方法是使用fstat获取它的 inode 编号,然后类似于遍历文件层次结构find / -inum以获取与其匹配的路径。(由于链接,可能有不止一个这样的文件路径。)

但你永远不需要这样做。正如其他人所说,如果您需要知道文件名,您应该将文件名作为参数。

于 2009-11-14T13:49:07.773 回答
4

你为什么要这样做?你的所有程序a.out都是从 shell 传递的,是一个打开的文件描述符,stdin。

用户不妨这样做:

cat inpfilename | ./a.out

现在您绝对没有要使用的文件名(/dev/stdin 除外)。

如果a.out需要使用文件名,为什么不将文件作为命令行参数呢?

于 2009-11-14T13:37:28.093 回答
2

只有父 shell 会知道这一点。程序 a.out 总是将其视为标准输入。

于 2009-11-14T13:38:04.583 回答
2

事实上,可以从 procfs 中获取文件名,因为 /proc/*/fd 包含指向打开文件的符号链接:

char filename[bufsize];
int sz = readlink("/proc/self/fd/0", filename, bufsize-1);
filename[sz] = 0;
puts(filename);
于 2018-04-19T18:10:29.863 回答
1

您的操作系统将为您的程序提供来自该文件的输入。这对您的程序是透明的,因此您看不到文件的名称。事实上,在某些情况下,您会收到并非来自文件的输入,例如:

ls | ./a.out

您所追求的是非常特定于系统的。可能更好的解决方案是将文件名作为参数传递。这样你就可以得到文件名,你可以打开它来阅读内容。

于 2009-11-14T13:39:09.087 回答
0

正如您所说,运行 a.out 的进程没有提供其标准输入的文件的文件名的概念。

调用应该是:

$ ./a.out inputfilename

argv并解析int main( int argc, char* argv[] ) { ... }

或者

$ ./a.out <<< "inputfilename"

并从标准输入获取文件名。

然后在 ac 中,您需要fopen该文件来读取它的内容。

于 2009-11-14T13:43:31.637 回答
0

我不认为这是可能的,因为<只是读取inpfilename到 STDIN 的内容。

如果您希望 inpfilename 可用于您的程序,但您还希望能够接受来自 STDIN 的数据,请将您的程序设置为接受文件名参数并将其打开到 FILE。如果没有给出参数,则将 STDIN 分配给您的 FILE。然后您的输入读取例程使用 fscanf 之类的函数而不是 scanf,并且您传入的 FILE 是指向 fopened 文件的链接或 STDIN。

于 2009-11-14T13:53:25.893 回答
0

fstat(0,sb)0 是标准输入文件描述符)将为您提供有关其所在设备的输入文件、大小、权限(称为mode )和 inode 的详细信息。

无论如何,您将无法说出它的路径:因为 unix inode 不知道它们属于哪条路径,而且从技术上讲(请参阅 参考资料ln)它们可能属于多个路径

于 2009-11-14T13:55:49.633 回答
0

天,

正如上面的答案所指出的,您所看到的只是打开的文件描述符标准输入。

如果您真的想这样做,您可以指定输入文件的第一行必须是文件本身的名称。

高温高压

于 2009-11-14T13:56:00.053 回答