$cc a.c
$./a.out < inpfilename
Quiero imprimir inpfilename en stdout. Cómo puedo hacer eso ? Gracias por la ayuda por adelantado…
$cc a.c
$./a.out < inpfilename
Quiero imprimir inpfilename en stdout. Cómo puedo hacer eso ? Gracias por la ayuda por adelantado…
No puede obtener el nombre del archivo exactamente como entrada; el shell manejará todas esas cosas de redirección sin decírtelo.
En el caso de un directo < file
redirección, puede recuperar una ruta de archivo asociada con stdin usando fstat
para obtener un número de inodo para él y luego recorrer la jerarquía de archivos de manera similar a find / -inum
para obtener un camino que coincida con él. (Puede haber más de una ruta de archivo de este tipo debido a los enlaces).
Pero nunca deberías necesitar hacer esto. Como han dicho otros, si necesita saber los nombres de archivo, debe tomar los nombres de archivo como argumentos.
Es probable que la operación ‘recuperar una ruta de archivo’ sea diabólicamente costosa, doblemente si tiene una gran cantidad de sistemas de archivos montados en NFS para escanear. Además, como se indica, es posible que no le dé una respuesta; las conexiones de tubería, por ejemplo, simplemente no tienen un nombre en el sistema de archivos.
–Jonathan Leffler
14 de noviembre de 2009 a las 14:02
Sí, de hecho. Es una pérdida en general.
– bobince
14 de noviembre de 2009 a las 14:10
u0b34a0f6ae
¿Por qué quieres hacer esto? Todo su programa a.out
se pasa desde el shell, es un descriptor de archivo abierto, stdin.
El usuario también podría hacer esto:
cat inpfilename | ./a.out
y ahora no tiene absolutamente ningún nombre de archivo para usar (excepto /dev/stdin).
Si a.out
necesita trabajar con nombres de archivos, ¿por qué no tomar el archivo como un argumento de línea de comandos?
Solo el caparazón principal lo sabrá. El programa, a.out siempre lo verá como stdin.
De hecho, es posible obtener el nombre de archivo de procfs, ya que /proc/*/fd contiene un enlace simbólico a los archivos abiertos:
char filename[bufsize];
int sz = readlink("/proc/self/fd/0", filename, bufsize-1);
filename[sz] = 0;
puts(filename);
Su sistema operativo proporcionará a su programa la entrada de este archivo. Esto es transparente para su programa y, como tal, no puede ver el nombre del archivo. De hecho, en algunas circunstancias, se le proporcionará información que no provienen de un archivo, como este:
ls | ./a.out
Lo que buscas es muy específico del sistema. Probablemente una mejor solución sea pasar el nombre del archivo como parámetro. De esa manera, obtiene el nombre del archivo y puede abrirlo para leer el contenido.
chen levy
Tal como lo expresa, el proceso que ejecuta a.out no tiene noción del nombre del archivo que proporciona su entrada estándar.
La invocación debe ser:
$ ./a.out inputfilename
y analizar argv
en int main( int argc, char* argv[] ) { ... }
o
$ ./a.out <<< "inputfilename"
Y obtenga el nombre de archivo de stdin.
Entonces en ac necesitas fopen
ese archivo para leer su contenido.
mlibby
No creo que sea posible, ya que <
solo lee el contenido de inpfilename
a STDIN.
Si desea que inpfilename esté disponible para su programa, pero también desea poder aceptar datos de STDIN, configure su programa para aceptar un argumento de nombre de archivo y ábralo en un ARCHIVO. Si no se proporciona ningún argumento, asigne STDIN a su ARCHIVO. Luego, su rutina de lectura de entrada usa funciones como fscanf en lugar de scanf, y el ARCHIVO que pasa es un enlace al archivo abierto o STDIN.