Función main y argumentos de la línea de comandos

Todos los programas de C++ deben tener una función main. Si se intenta compilar un programa de C++ sin una función main, el compilador genera un error. (Las bibliotecas static y las bibliotecas de vínculos dinámicos carecen de función main). La función main es donde el código fuente empieza a ejecutarse, pero antes de que un programa entre en la función main, todos los miembros de clase static sin inicializadores explícitos se establecen en cero. En Microsoft C++, los objetos static globales también se inicializan antes de entrar en main. A la función main se le aplican varias restricciones que no se aplican a otras funciones de C++. La función main:

  • No se puede sobrecargar (vea Sobrecarga de funciones).
  • No se puede declarar como inline.
  • No se puede declarar como static.
  • Su dirección no se puede tomar.
  • No se puede llamar desde un programa de un usuario.

Signatura de la función main

La función main no tiene una declaración porque está integrada en el lenguaje. Si la tuviera, la sintaxis de declaración de main tendría este aspecto:

int main();
int main(int argc, char *argv[]);

Si no se especifica ningún valor devuelto en main, el compilador proporciona un valor devuelto de cero.

Argumentos de línea de comandos estándar

Los argumentos para main permiten realizar un práctico análisis de línea de comandos de los argumentos. El lenguaje define los tipos argc y argv. Los nombres argc y argv son tradicionales, pero se les puede asignar el nombre que se quiera.

Las definiciones de los argumentos son las siguientes:

argc
Un entero que contiene el número de argumentos que aparecen detrás de argv. El parámetro argc es siempre mayor o igual que 1.

argv
Una matriz de cadenas terminadas en null que representan los argumentos de la línea de comandos especificados por el usuario del programa. Por convención, argv[0] es el comando con el que se invoca el programa. argv[1] es el primer argumento de la línea de comandos. El último argumento de la línea de comandos es argv[argc - 1], y argv[argc] siempre es NULL.

Para obtener información sobre cómo suprimir el procesamiento de la línea de comandos, vea Personalización del procesamiento de la línea de comandos de C++.

Nota:

Por convención, argv[0] es el nombre de archivo del programa. Sin embargo, en Windows es posible generar un proceso mediante CreateProcess. Si se usa tanto el primer argumento como el segundo (lpApplicationName y lpCommandLine), argv[0] no puede ser el nombre del archivo ejecutable. Puede usar GetModuleFileName para recuperar el nombre del archivo ejecutable y su ruta de acceso completa.

Extensiones específicas de Microsoft

En las siguientes secciones se describe el comportamiento específico de Microsoft.

La función wmain y la macro _tmain

Si diseña el código fuente para que use characters anchos Unicode, puede usar el punto de entrada wmain específico de Microsoft, que es la versión de characters ancho de main. Esta es la sintaxis de declaración de facto de wmain:

int wmain();
int wmain(int argc, wchar_t *argv[]);

También puede usar la macro _tmain específica de Microsoft, que es una macro de preprocesador definida en tchar.h. _tmain se resuelve en main a menos que se defina _UNICODE. En ese caso, _tmain se resuelve en wmain. La macro _tmain y otras macros que comienzan por _t son útiles en códigos que deben compilar versiones independientes de los juegos de characteres anchos y estrechos. Para obtener más información, vea Uso de asignaciones de texto genérico.

void devuelto de main

Como extensión de Microsoft, las funciones main y wmain se pueden declarar para que devuelvan void (ningún valor devuelto). Esta extensión también está disponible en otros compiladores, pero su uso no se recomienda. Está disponible para simetría cuando main no devuelve un valor.

Si declara que main o wmain devuelvan void, no se puede devolver un código exit al proceso primario o al sistema operativo mediante una instrucción return. Para devolver un código exit cuando main o wmain se declaran como void, debe utilizar la función exit.

El argumento de la línea de comandos envp

Las signaturas main o wmain permiten una extensión específica de Microsoft opcional para acceder a variables de entorno. Esta extensión también es común en otros compiladores de sistemas Windows y UNIX. El nombre del parámetro de entorno envp es tradicional, pero puede llamarlo como quiera. Estas son las declaraciones de facto de las listas de argumentos que incluyen el parámetro de entorno:

int main(int argc, char* argv[], char* envp[]);
int wmain(int argc, wchar_t* argv[], wchar_t* envp[]);

envp
El parámetro envp opcional es una matriz de cadenas que representan las variables establecidas en el entorno de usuario. Esta matriz termina con una entrada NULL. Se puede declarar como una matriz de punteros a char (char *envp[]) o como un puntero a punteros a char (char **envp). Si su programa usa wmain en lugar de main, utilice el tipo de datos wchar_t en lugar de char.

El bloque de entorno que se pasa a main y a wmain es una copia "inmóvil" del entorno actual. Si, más adelante, cambia el entorno llamando a putenv o a _wputenv, el entorno actual (devuelto por getenv o _wgetenv, o por las variables _environ o _wenviron) cambiará, pero no el bloque al que envp apunta. Para obtener más información sobre cómo suprimir el procesamiento del entorno, vea Personalización del procesamiento de la línea de comandos de C++. El argumento envp es compatible con el estándar C89, pero no con los estándares de C++.

Argumentos de ejemplo en main

En el ejemplo siguiente se muestra cómo usar los argumentos argc, argv y envp en main:

// argument_definitions.cpp
// compile with: /EHsc
#include <iostream>
#include <string.h>

using namespace std;
int main( int argc, char *argv[], char *envp[] )
{
    bool numberLines = false;    // Default is no line numbers.

    // If /n is passed to the .exe, display numbered listing
    // of environment variables.
    if ( (argc == 2) && _stricmp( argv[1], "/n" ) == 0 )
         numberLines = true;

    // Walk through list of strings until a NULL is encountered.
    for ( int i = 0; envp[i] != NULL; ++i )
    {
        if ( numberLines )
            cout << i << ": "; // Prefix with numbers if /n specified
        cout << envp[i] << "\n";
    }
}

Analizar los argumentos de la línea de comandos de C++

Las reglas de análisis de la línea de comandos usadas por el código de Microsoft C/C++ son específicas de Microsoft. El código de inicio del entorno de ejecución utiliza estas reglas al interpretar los argumentos proporcionados en la línea de comandos del sistema operativo:

  • Los argumentos van delimitados por espacio en blanco, que puede ser un carácter de espacio o una tabulación.

  • El primer argumento (argv[0]) se trata de forma especial. Representa el nombre del programa. Dado que debe ser un nombre de ruta válido, se permiten partes entre comillas dobles ( " ). Las comillas dobles no se incluyen en la salida argv[0]. Las partes delimitadas por comillas dobles impiden la interpretación de un charácter de espacio o tabulación como final del argumento. No se aplican las últimas reglas de esta lista.

  • Una cadena delimitada por comillas dobles se interpreta como un solo argumento, que puede contener characteres de espacios en blanco. Se puede incrustar una cadena entre comillas dentro de un argumento. El símbolo de inserción (^) no se reconoce como charácter de escape ni como delimitador. Dentro de una cadena entrecomillada, un par de comillas dobles se interpreta como una sola marca de comilla doble con escape. Si la línea de comandos finaliza antes de que se encuentre una comilla doble de cierre, todos los characteres leídos hasta ahora se muestran como el último argumento.

  • Un signo de comillas dobles precedido por una barra diagonal inversa ( \" ) se interpreta como signo de comillas dobles literal ( " ).

  • Las barras diagonales inversas se interpretan literalmente, a menos que precedan inmediatamente a unas comillas dobles.

  • Si un número par de barras diagonales inversas va seguido de un signo de comillas dobles, se coloca una barra diagonal inversa ( \ ) en la matriz argv por cada par de barras diagonales inversas ( \\ ) y el signo de comillas dobles (" ) se interpreta como delimitador de cadena.

  • Si un número impar de barras diagonales inversas va seguido de una comilla doble, se coloca una barra diagonal inversa ( \ ) en la matriz argv por cada par de barras diagonales inversas ( \\ ). La barra diagonal resmaintante interpreta la comilla doble como una secuencia de escape, lo que hace que se coloque una marca de comilla doble literal (") en argv.

Ejemplo de análisis de argumentos de la línea de comandos

En el programa siguiente se muestra cómo se pasan los argumentos de la línea de comandos:

// command_line_arguments.cpp
// compile with: /EHsc
#include <iostream>

using namespace std;
int main( int argc,      // Number of strings in array argv
          char *argv[],   // Array of command-line argument strings
          char *envp[] )  // Array of environment variable strings
{
    int count;

    // Display each command-line argument.
    cout << "\nCommand-line arguments:\n";
    for( count = 0; count < argc; count++ )
         cout << "  argv[" << count << "]   "
                << argv[count] << "\n";
}

Resultados del análisis de las líneas de comandos

En la tabla siguiente se muestra una entrada de ejemplo y la salida esperada para mostrar las reglas de la lista anterior.

Entrada de la línea de comandos argv[1] argv[2] argv[3]
"abc" d e abc d e
a\\b d"e f"g h a\\b de fg h
a\\\"b c d a\"b c d
a\\\\"b c" d e a\\b c d e
a"b"" c d ab" c d

Expansión de caracteres comodín

Opcionalmente, el compilador de Microsoft permite usar characteres comodín, el signo de interrogación (?) y asteriscos (*) para especificar argumentos de nombre de archivo y ruta de acceso en la línea de comandos.

Los argumentos de la línea de comandos se controlan mediante una rutina interna del código de inicio del entorno de ejecución que, de forma predeterminada, no expande los caracteres comodín en cadenas independientes en la matriz de cadenas argv. Para permitir la expansión de caracteres comodín, puede incluir el archivo setargv.obj (archivo wsetargv.obj si es wmain) en las opciones del compilador /link o en la línea de comandos LINK.

Para obtener más información sobre las opciones del vinculador de inicio en tiempo de ejecución, consulte Opciones de vínculo.

Personalización del procesamiento de línea de comandos de C++

Si el programa no acepta argumentos de línea de comandos, puede suprimir la rutina de procesamiento de la línea de comandos para guardar una pequeña cantidad de espacio. Para suprimir su uso, incluya el archivo noarg.obj (para main y wmain) en sus opciones del compilador /link o su línea de comandos LINK .

Del mismo modo, si nunca tiene acceso a la tabla de entorno a través del argumento envp , puede suprimir la rutina de procesamiento del entorno interna. Para suprimir su uso, incluya el archivo noenv.obj (para main y wmain) en sus opciones del compilador /link o su línea de comandos LINK .

El programa puede realizar llamadas a la familia de rutinas spawn o exec de la biblioteca en tiempo de ejecución de C. Si lo hace, no debe suprimir la rutina de procesamiento de entorno, puesto que se utiliza para pasar un entorno del proceso primario al proceso secundario.

Consulte también

Conceptos básicos