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