2010-06-11 16 views
7

¿Qué se considera la mejor práctica cuando se hace referencia al nombre de un programa? He visto:Práctica recomendada al hacer referencia al nombre de un programa en C

#define PROGRAM_NAME "myprog" 
printf("this is %s\n", PROGRAM_NAME); 

así como:

printf("this is %s\n", argv[0]); 

sé, que el segundo enfoque me dará ./myprog en lugar de myprog cuando el programa no se llama desde $PATH y que el primer enfoque garantizará consistencia con respecto al nombre del programa.

Pero, ¿hay algo más que hace que un enfoque sea superior al otro?

+0

Si desea una constante, utilizar una constante (es decir, a nivel mundial, 'const char * const PROGRAM_NAME = "miprog";'). Al hacerlo, se asegurará de que la cadena solo se almacene una vez en la memoria. – mk12

Respuesta

5

El segundo enfoque es superior cuando se tienen varios enlaces. En los sistemas * nix, a veces el comportamiento depende de cómo llame a un programa. Tan difícil codificación del nombre del programa sería claramente un problema, nunca podría verificar eso.

+0

¿qué significa esto "el comportamiento depende de cómo llame a un programa"? Realmente no puedo entenderlo. – guest

+0

@guest: por ejemplo, 'gcc' y' g ++ 'pueden ser el mismo ejecutable, que verifica el nombre con el que se invocó y modifica las opciones del enlazador en consecuencia. No puedo recordar si realmente es o no. –

+0

Ejemplo: de forma predeterminada, grep imprime las líneas correspondientes. Además, están disponibles tres programas variantes egrep, fgrep y rgrep. egrep es lo mismo que grep -E. fgrep es lo mismo que grep -F. rgrep es lo mismo que grep -r. –

0

La primera es superior a la última cuando no tiene a mano el argv.

#define PROGRAM_NAME "myprog" 

void salute() 
{ 
    // no argv available 

    printf("Hello from %s\n", PROGRAM_NAME); 
} 

void main(int argc, char** argv) 
{ 
    salute(); 
} 
+0

¿Eso hace una gran diferencia? No creo que 'argc' y' argv' cuesten demasiado – guest

+0

ah. Ahora entiendo lo que quieres decir. Sí, tiene perfecto sentido – guest

+1

Entiendo tu punto, pero en tu ejemplo básicamente estás creando una variable global. Si necesita program_name, páselo (argv) como parámetro para saludar() y su problema está resuelto. – MJB

0

depende de si es argv en su alcance o no ...

5

Traté de tomar lo mejor de ambos mundos:

char const * program_name; 

int main(int argc, char **argv) { 
    program_name = argv[0]; 
    //... 
} 

Si necesita program_name que esté disponible en algún otro archivo se puede declarar así:

extern char const * program_name; 

declaro "char const * "porque quiero que sea un puntero que apunta a datos const. No estoy seguro si hice bien esta parte.

+0

No está mal.Dejando de lado la pregunta de cuál es mejor respondiendo "ambos", pero no está mal. – MJB

1

El segundo enfoque podría darle también cadenas como /usr/bin/myprog si lo ejecutó de esa manera; basename debería dar el nombre del ejecutable (que se podría considerar como el nombre de tu programa) ... a menos que esté enlazado simbólicamente ... (en ese caso, tienes el nombre del enlace ... que podría usarse) hacer elecciones de algún tipo en el comportamiento del programa).

El primer acercamiento "fija" el nombre del programa a lo que el programador quería, no importa lo que el usuario cambió el nombre del archivo ejecutable o se enlazan (o incluso hardlinked)

+0

Sí, he usado productos donde parece que tiene varios ejecutables, pero en realidad es solo uno con múltiples enlaces a él. Esto puede parecer una locura, pero es una buena manera de mantener múltiples herramientas sincronizadas a través de múltiples revisiones. –

2

normalmente utilizo argv[0] o basename(argv[0]) si es posible. Desde el punto de vista del usuario, creo que si renombran o enlazan un ejecutable (o alguien más hace eso por ellos), entonces quieren que aparezcan mensajes con el nombre que están usando, no con otro nombre que fue compilado como, que ellos pueden o no conocer.

Del mismo modo, si se descubre en el futuro que se desea compilar su programa bajo diferentes nombres con diferentes opciones, para dar diferentes versiones, ¿quiere envolver un #ifndef alrededor de ese #define y asegúrese de que está definido a través de la línea de comandos del compilador : -DPROGRAM_NAME=myprog_demo, ¿o solo quieres hacerlo y funciona?

La excepción podría ser que si sus instrucciones de uso son un extracto de una página de manual u otra documentación, entonces posiblemente quiera cablear el nombre del programa en eso. Pero entonces probablemente tampoco usaría el #define.

implementaciones no necesitan proporcionar argv[0], sin embargo, por lo que para las mejores prácticas portátiles gestionar el caso también. Por otra parte, si su sistema no lo proporciona, probablemente el usuario tampoco vaya a ver mensajes en ningún tipo de terminal.

Por cierto:

#define PROGRAM_NAME "myprog" 
puts("this is " PROGRAM_NAME); 
+0

'basename' no es portátil. Solo es requerido por POSIX (en libgen.h). Además, tenga en cuenta que puede modificar la cadena que le da, y el puntero devuelto puede ser un desplazamiento del puntero original, o una cadena asignada estáticamente (así que no intente liberar lo que le da, y don Trate de liberar lo que * le dio * inmediatamente después). Lo evitaría a menos que esté 100% seguro de que comprende la administración de memoria involucrada y que no le importa la portabilidad. – mk12

+1

Por lo tanto, "si es posible". Pero tienes razón en que 'basename (argv [0])' es en sí mismo una expresión ligeramente dudosa, supone que no estás planeando usar los argumentos de nuevo. –

1

No responde exactamente a su pregunta de mejores prácticas de programación, pero creo que también hay que tener en cuenta qué es lo mejor para el usuario. yo personalmente prefiero los programas refiriéndose a sí mismos utilizando argv[0], es decir, el comando estaba llamando, y no un nombre aleatorio que el codificador codificado en el programa. Unos pocos ejemplos en los que un nombre codificado es molesto o al menos no es útil:

  • que he creado un enlace a un programa de
  • He cambió el nombre del binario por alguna razón
  • tengo varios ejecutables con los mismos nombres base en diferentes directorios en mi $PATH
  • Un programa me da consejos sobre otras formas de llamarlo, por ejemplo, en mensajes de "uso"

La única situación en la que preferiría un nombre de programa codificado es cuando estoy usando aplicaciones de GUI. No me gustaría ver "~/foo/bar.pl" como título de ventana.

Cuestiones relacionadas