$cc a.c
$./a.out < inpfilename
我想在标准输出上打印 inpfilename。我怎么做 ?我在这里先向您的帮助表示感谢...
$cc a.c
$./a.out < inpfilename
我想在标准输出上打印 inpfilename。我怎么做 ?我在这里先向您的帮助表示感谢...
您无法获得与输入完全相同的文件名;shell 会在不告诉你的情况下处理所有重定向的东西。
在直接< file
重定向的情况下,您可以检索与 stdin 关联的文件路径,方法是使用fstat
获取它的 inode 编号,然后类似于遍历文件层次结构find / -inum
以获取与其匹配的路径。(由于链接,可能有不止一个这样的文件路径。)
但你永远不需要这样做。正如其他人所说,如果您需要知道文件名,您应该将文件名作为参数。
你为什么要这样做?你的所有程序a.out
都是从 shell 传递的,是一个打开的文件描述符,stdin。
用户不妨这样做:
cat inpfilename | ./a.out
现在您绝对没有要使用的文件名(/dev/stdin 除外)。
如果a.out
需要使用文件名,为什么不将文件作为命令行参数呢?
只有父 shell 会知道这一点。程序 a.out 总是将其视为标准输入。
事实上,可以从 procfs 中获取文件名,因为 /proc/*/fd 包含指向打开文件的符号链接:
char filename[bufsize];
int sz = readlink("/proc/self/fd/0", filename, bufsize-1);
filename[sz] = 0;
puts(filename);
您的操作系统将为您的程序提供来自该文件的输入。这对您的程序是透明的,因此您看不到文件的名称。事实上,在某些情况下,您会收到并非来自文件的输入,例如:
ls | ./a.out
您所追求的是非常特定于系统的。可能更好的解决方案是将文件名作为参数传递。这样你就可以得到文件名,你可以打开它来阅读内容。
正如您所说,运行 a.out 的进程没有提供其标准输入的文件的文件名的概念。
调用应该是:
$ ./a.out inputfilename
argv
并解析int main( int argc, char* argv[] ) { ... }
或者
$ ./a.out <<< "inputfilename"
并从标准输入获取文件名。
然后在 ac 中,您需要fopen
该文件来读取它的内容。
我不认为这是可能的,因为<
只是读取inpfilename
到 STDIN 的内容。
如果您希望 inpfilename 可用于您的程序,但您还希望能够接受来自 STDIN 的数据,请将您的程序设置为接受文件名参数并将其打开到 FILE。如果没有给出参数,则将 STDIN 分配给您的 FILE。然后您的输入读取例程使用 fscanf 之类的函数而不是 scanf,并且您传入的 FILE 是指向 fopened 文件的链接或 STDIN。
(fstat(0,sb)
0 是标准输入文件描述符)将为您提供有关其所在设备的输入文件、大小、权限(称为mode )和 inode 的详细信息。
无论如何,您将无法说出它的路径:因为 unix inode 不知道它们属于哪条路径,而且从技术上讲(请参阅 参考资料ln
)它们可能属于多个路径。
天,
正如上面的答案所指出的,您所看到的只是打开的文件描述符标准输入。
如果您真的想这样做,您可以指定输入文件的第一行必须是文件本身的名称。
高温高压