Paso de parámetros a través de la línea de órdenes



Es frecuente encontrar programas en C cuyo aspecto es aproximadamente el siguiente:

#include<stdio.h> 

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

		int i; 

		printf("Argumentos de la línea de órdenes\n\n"); 

		for(i=0; i<argc; i++) 

				printf("El argumento %d es %s\n", i, argv[i]); 

		printf("\n\nTerminación normal del programa.\n"); 

		return 0; 

} 

Comentarios .- Al ejecutar este programa se muestran todos los argumentos introducidos a través de la línea de órdenes. Véase a continuación el resultado de ejecutar el programa:
[maxus~:]% ./a.out 1 2 3 4
Argumentos de la línea de órdenes

El argumento 0 es ./a.out
El argumento 1 es 1
El argumento 2 es 2
El argumento 3 es 3
El argumento 4 es 4


Terminación normal del programa.

Comentarios .- Como se puede apreciar, el argumento 0 es el nombre del programa. Nos hemos limitado a escribir en pantalla las cadenas recibidas a través de argv[] , pero nada impide traducirlas a un formato binario y operar con ellas.

Ejercicios resueltos


  1. Ejercicio 0108r01.- Escribir un programa que calcule la media de una lista de int . El programa recibirá el número de elementos de que consta la lista como argumento de la línea de órdenes. Recuérdese la función strtol() . Pista: utilizar una variable como acumulador.
    #include<stdio.h>
    #include<stdlib.h>
    
    int main(int argc, char * argv[])
     {
      int num_datos; /* recibido a través de la línea de órdenes */
      int suma, temp; /* acumulador y número leído, respectivamente */
      int i;   /* índice */
      if (argc != 2)
       {
        printf("\n\nUtilización: ./a.out número\n\n");
        exit(1);
       }
      else
       {
        num_datos = strtol(argv[1], NULL, 10);
        suma = 0;
        printf("\n\n");
        for(i=0;i<num_datos;i++)
         {
          printf("Deme el dato %d: ", i);
          scanf("%d", &temp);
          suma += temp;
         }
        printf("\n\nLa media es %d.\n\n", suma/num_datos);
       }
      printf("\n\nTerminación normal\n\n");
      return 0;
     }
    
  2. Ejercicio 0108r02.- Escribir un programa que admita una contraseña a través de la línea de órdenes, esto es, en el momento de su arranque. Si la contraseña no es correcta, el programa mostrará un mensaje y saldrá. Si es correcta, el programa mostrará la suma de los valores numéricos de los caracteres de que consta la clave.
    #include<stdio.h>
    
    int main(int argc, char * argv[])
     {
      char clave[] = "mephistopheles";
      int i, suma = 0;
      if (argc != 2)
       {
        printf("\n\nUtilización: ./a.out clave\n\n");
        exit(1);
       }
      else
       {
        if (strcmp(clave, argv[1]) != 0)
         {
          printf("\n\nLa clave no es correcta.\n\n");
         }
        else
         {
          for(i=0;i<strlen(clave);i++)
           suma += clave[i];
          printf("\n\nLa clave es correcta - %d\n\n", suma);
         }
       }
      printf("\n\nTerminación normal.\n\n");
      return 0;
     }
    
    El resultado de ejecutar este programa es como sigue:
    [maxus~:] coti% ./a.out clave
    
    
    La clave no es correcta.
    
    
    
    Terminación normal.
    
    [maxus~:] coti% ./a.out mephistopheles
    
    
    La clave es correcta - 1514
    
    
    
    Terminación normal.
    
    Obsérvese que se hace uso del valor ASCII de los caracteres de la clave para calcular la suma. Evidentemente, este programa no ofrece seguridad alguna. ¿Qué ocurre si se ejecuta la sentencia cat a.out ? ¿Sería posible mejorar la seguridad del programa?

  3. Ejercicio 0108r03.- Escribir un programa que muestre un menú en pantalla, de la forma " L)eer C)alcular M)ostrar S)alir A)yuda ". El programa, una vez mostrado este menú, debe admitir una letra (la situada a la izquierda del paréntesis) indicando al usuario la opción seleccionada. Si el usuario introduce una opción incorrecta, deberá mostrarse un mensaje de error.
    #include<stdio.h>
    
    int main(int argc, char * argv[])
     {
      char menu[] = "L)eer C)alcular M)ostrar S)alir A)yuda";
      char opcion;
      do
       {
        printf("%s ", menu);
        scanf("%c%*c", &opcion);
        opcion = toupper(opcion);
        switch(opcion)
         {
          case 'L': printf("\nLeer...\n\n");break;
          case 'C': printf("\nCalcular...\n\n");break;
          case 'M': printf("\nEscribir...\n\n");break;
          case 'S': printf("\nSalir...\n\n");break;
          case 'A': printf("\nAyuda...\n\n");break;
          default: printf("\nOpción incorrecta.\n\n");break;
         }
       }
       while (opcion != 'S');
      printf("\n\nTerminación normal\n\n");
      return 0;
     }
    El resultado de ejecutar este programa es como sigue:
    [maxus:~] coti% ./a.out
    L)eer C)alcular M)ostrar S)alir A)yuda l
    
    Leer...
    
    L)eer C)alcular M)ostrar S)alir A)yuda c
    
    Calcular...
    
    L)eer C)alcular M)ostrar S)alir A)yuda m
    
    Escribir...
    
    L)eer C)alcular M)ostrar S)alir A)yuda a
    
    Ayuda...
    
    L)eer C)alcular M)ostrar S)alir A)yuda s
    
    Salir...
    
    
    
    Terminación normal
    
    [maxus:~] coti% 
    
  4. Ejercicio 0108r04.- Escribir un programa que admita una matriz 3x3 de float a través de la línea de órdenes.
    /*
     Escribir un programa que admita una matriz 3x3 de float
     a través de la línea de órdenes.
    */
    
    
    #include<stdio.h>
    #include<stdlib.h>
    
    #define FILAS 3
    #define COLUMNAS 3
    
    int main(int argc, char * argv[])
     {
      float matriz[FILAS][COLUMNAS];
      int num_datos = FILAS*COLUMNAS+1;
      int i, fila, columna;
      if (argc != num_datos)
       {
        printf("\n\nUtilización: ./a.out 9 números\n\n");
        exit(1);
       }
      else
       {
    
        printf("\n\n");
        i=1;
        for(fila=0;fila<FILAS;fila++)
         for(columna=0;columna<COLUMNAS;columna++)
         {
          matriz[fila][columna] = strtof(argv[i++],NULL);
         }
        printf("\n\nLa matriz proporcionada era:\n\n");
        for(fila=0;fila<FILAS;fila++)
         {
          printf("|");
          for(columna=0;columna<COLUMNAS;columna++)
           printf("%6.2f", matriz[fila][columna]);
          printf("|\n");
         }
       }
    
      printf("\n\nTerminación normal\n\n");
      return 0;
     }
    El resultado de ejecutar este programa es como sigue:
    [maxus:~] coti% ./a.out 1 2 3 4 5 6 7 8 9
    
    
    
    
    La matriz proporcionada era:
    
    |  1.00  2.00  3.00|
    |  4.00  5.00  6.00|
    |  7.00  8.00  9.00|
    
    
    Terminación normal
    
    
    Comentarios .- ¿Cómo funciona este programa? La única dificultad es almacenar los números proporcionados a través de la línea de órdenes en las posiciones correctas dentro de la matriz. Suponemos que los números se han proporcionado por filas, que es el orden habitual de almacenamiento de matrices en C. Entonces es cuestión de ir incrementando el índice que recorre argv[] , comenzando en la posición 1 (la posición 0 es el nombre del programa, a.out en este caso). La traducción a formato binario se efectúa mediante strtof() , ya conocido. No debemos olvidar que es preciso incluir stdlib.h ; en caso contrario, la traducción podría no ser correcta.

  5. Ejercicio 0108r05.- Escribir un programa que admita dos matrices 3x3 de float a través de la línea de órdenes. El programa debe mostrar en pantalla la suma, resta y producto de estas matrices.
    
    #include<stdio.h>
    #include<stdlib.h>
    
    #define FILAS 3
    #define COLUMNAS 3
    
    void escribir(		float m[FILAS][COLUMNAS]);
    void  sumar(		float m1[FILAS][COLUMNAS], float m2[FILAS][COLUMNAS],
    			float r[FILAS][COLUMNAS]);
    void  restar(float m1[FILAS][COLUMNAS], float m2[FILAS][COLUMNAS],
    			float r[FILAS][COLUMNAS]);
    void  multiplicar(	float m1[FILAS][COLUMNAS], float m2[FILAS][COLUMNAS],
    			float r[FILAS][COLUMNAS]);
    int main(int argc, char * argv[])
     {
      float m1[FILAS][COLUMNAS], m2[FILAS][COLUMNAS];
      float suma[FILAS][COLUMNAS], resta[FILAS][COLUMNAS];
      float producto[FILAS][COLUMNAS];
      int num_datos = 2*FILAS*COLUMNAS+1;
      int i, fila, columna;
      if (argc != num_datos)
       {
        printf("\n\nUtilización: ./a.out 18 números\n\n");
        exit(1);
       }
      else
       {
        printf("\n\n");
        i=1;
        /* Leemos la primera matriz */
        for(fila=0;fila<FILAS;fila++)
         for(columna=0;columna<COLUMNAS;columna++)
         {
          m1[fila][columna] = strtof(argv[i++], NULL);
         }
        /* Leemos la segunda matriz */
        for(fila=0;fila<FILAS;fila++)
         for(columna=0;columna<COLUMNAS;columna++)
         {
          m2[fila][columna] = strtof(argv[i++], NULL);
         }
        /*Mostramos ambas matrices */
        printf("\n\nLas matrices proporcionadas son:\n\n");
        escribir(m1);
        printf("\n\ny\n\n");
        escribir(m2);
        /* Calculos */
        sumar(m1, m2, suma);
        restar(m1, m2, resta);
        multiplicar(m1, m2, producto);
        /* Impresión de resultados */
        printf("\n\nLa matriz suma es:\n\n");
        escribir(suma);
        printf("\n\nLa matriz resta es:\n\n");
        escribir(resta);
        printf("\n\nLa matriz producto es:\n\n");
        escribir(producto);
       }
    
      printf("\n\nTerminación normal\n\n");
      return 0;
     }
     
    void escribir(float m[FILAS][COLUMNAS])
     {
      int fila, columna;
      for(fila=0;fila<FILAS;fila++)
       {
        printf("|");
        for(columna=0;columna<COLUMNAS;columna++)
         printf("%6.2f", m[fila][columna]);
        printf("|\n");
       }
     }
    
    void  sumar(float m1[FILAS][COLUMNAS], float m2[FILAS][COLUMNAS],
    	float r[FILAS][COLUMNAS])
     {
      int i,j;
      for(i=0;i<FILAS;i++)
       for(j=0;j<COLUMNAS;j++)
        r[i][j] = m1[i][j]+m2[i][j];
     }
     
    void  restar(float m1[FILAS][COLUMNAS], float m2[FILAS][COLUMNAS],
    	float r[FILAS][COLUMNAS])
     {
      int i,j;
      for(i=0;i<FILAS;i++)
       for(j=0;j<COLUMNAS;j++)
        r[i][j] = m1[i][j]-m2[i][j];
     }
    
    void  multiplicar(float m1[FILAS][COLUMNAS], float m2[FILAS][COLUMNAS],
    	float r[FILAS][COLUMNAS])
     {
      int i,j, k;
      for(i=0;i<FILAS;i++)
       for(j=0;j<COLUMNAS;j++)
        {
         r[i][j]=0.0;
         for(k=0;k<FILAS;k++)
          r[i][j] += m1[i][k]*m2[k][j];
        }
     }
    El resultado de ejecutar este programa es como sigue:
    [maxus~:] coti% ./a.out 1 2 3 4 5 6 7 8 9 1 0 0 0 1 0 0 0 1
    
    Las matrices proporcionadas son:
    
    |  1.00  2.00  3.00|
    |  4.00  5.00  6.00|
    |  7.00  8.00  9.00|
    
    
    y
    
    |  1.00  0.00  0.00|
    |  0.00  1.00  0.00|
    |  0.00  0.00  1.00|
    
    
    La matriz suma es:
    
    |  2.00  2.00  3.00|
    |  4.00  6.00  6.00|
    |  7.00  8.00 10.00|
    
    
    La matriz resta es:
    
    |  0.00  2.00  3.00|
    |  4.00  4.00  6.00|
    |  7.00  8.00  8.00|
    
    
    La matriz producto es:
    
    |  1.00  2.00  3.00|
    |  4.00  5.00  6.00|
    |  7.00  8.00  9.00|
    
    
    Terminación normal
    
  6. Ejercicio 0108r06.- Escribir un programa que admita como argumento de la línea de órdenes una frase formada por dos cadenas y un número double . El programa debe mostrar en pantalla la concatenación de ambas cadenas, seguida por el doble del valor del número introducido. Pista: estúdiese la función strcat() , que forma parte de string.h .
    #include<stdio.h>
    #include<stdlib.h>
    
    int main(int argc, char * argv[])
     { 
      int longitud_1, longitud_2, total;
      float num;
      char * concatenacion;
      /*
       Debemos recibir cuatro datos:
       
       – Nombre del programa
       – Primera cadena
       – Segunda cadena
       – Número
      */
      if (argc != 4)
       {
        printf("\n\nUtilización: ./a.out cadena cadena número\n\n");
        exit(1);
       }
      else
       {
        longitud_1 = strlen(argv[1]);
        longitud_2 = strlen(argv[2]);
        total = longitud_1 + longitud_2;
        concatenacion = (char *)malloc(total+1);
        strcat(concatenacion, argv[1]);
        strcat(concatenacion, argv[2]);
        num = strtof(argv[3], NULL)*2.0;
        printf("\n\nResultado: %s - %f\n", concatenacion, num);
       }
    
      printf("\n\nFin del programa\n\n");
      return 0;
     }
    El resultado de ejecutar este programa es como sigue:
    [maxus:–] coti% ./a.out pepe juan 6.0
    
    
    Resultado: pepejuan - 12.000000
    
    
    Fin del programa
    
    [maxus:–] coti% ./a.out luis manolo pedro 9
    
    
    Utilización: ./a.out cadena cadena n?mero
    
    [maxus:–] coti% ./a.out "luis manolo" "pedro eloy" 13.0
    
    
    Resultado: luis manolopedro eloy - 26.000000
    
    
    Fin del programa
    
    [maxus:–] coti% clear
    
    Comentarios