// dades que arriben abans de main()

Arguments de main()

Fins ara tots els programes demanaven dades amb scanf un cop ja en marxa. Aquí en reben abans de començar: les paraules que escrius just després del nom del programa a la terminal.

argc i argv

main() pot rebre dos paràmetres especials: quants arguments s'han escrit a la terminal, i quins són.

Capçalera

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

Exemple d'execució

$ ./saluda hola món

Amb aquesta crida: argc val 3, i argv és un vector de 3 cadenes: argv[0] = "./saluda" (el nom amb què s'ha invocat el programa), argv[1] = "hola", argv[2] = "món". Fixa't que argv[0] sempre hi és, encara que no passis cap argument propi — per això argc mai és 0.

Recórrer els arguments

for (i = 0; i < argc; i++) {
    printf("argv[%d] = %s\n", i, argv[i]);
}

Exactament com recorries un vector normal: un bucle de 0 a argc - 1.

Convertir-los a nombres

Tots els elements d'argv són cadenes de text — encara que escriguis un número a la terminal, arriba com a char *, no com a int.

#include <stdlib.h>

int a = atoi(argv[1]);   // "5" -> 5
double x = atof(argv[2]); // "3.14" -> 3.14

atoi ("ASCII to integer") i atof ("ASCII to float") venen de <stdlib.h>. Si el text no és un número vàlid, atoi no avisa de res: simplement retorna 0.

Validar que n'hi ha prou

Accedir a argv[2] quan l'usuari només n'ha escrit un és un error clàssic (llegir fora dels límits del vector). Cal comprovar argc abans.

if (argc < 3) {
    printf("Ús: %s <a> <b>\n", argv[0]);
    return 1;
}

Un missatge d'ús que es construeix amb argv[0] sempre queda correcte, encara que algú canviï el nom de l'executable. Retornar 1 (en lloc de 0) és la convenció per dir-li a la terminal "alguna cosa ha anat malament".

Mira el programa rebre arguments pas a pas

La primera línia del terminal simula la crida des de la consola; la resta és el que el programa mateix va imprimint.

Arguments bàsics

Validació

Codi

Variables

NomValor

argv

Terminal

Pas 1 / 1

Problemes per resoldre

Sense solució ni comprovació automàtica: escriu el programa, compila'l (gcc programa.c -o programa) i prova'l des de la terminal amb els arguments de l'exemple. Les pistes són plegades perquè les obris només si les necessites.

1. Saluda per argument

Escriu un programa que rebi un nom com a argument i saludi. Si no se li passa cap argument, mostra un missatge d'ús.

$ ./saluda Jordi
Hola, Jordi!

$ ./saluda
Ús: ./saluda <nom>
Pistes

Comprova argc abans de tocar argv[1]: si argc < 2, encara no hi ha cap nom.

2. Suma de diversos arguments

Escriu un programa que sumi tots els arguments rebuts (poden ser-ne 2, 5, o cap), no només dos de fixos.

$ ./suma 3 5 8 1
Suma: 17
Pistes

Un bucle que recorri argv des de l'1 (saltant-te argv[0], que és el nom del programa) fins a argc - 1, convertint cada element amb atoi() i acumulant-lo.

3. Compta i majúscula

Mostra quants arguments ha rebut el programa (sense comptar argv[0]) i mostra'ls tots en majúscules.

$ ./mostra hola amic
2 arguments:
HOLA
AMIC
Pistes

El nombre d'arguments propis és argc - 1.

Per passar cada paraula a majúscules, recorre'n els caràcters i aplica toupper() (de <ctype.h>) un per un, com vas fer al capítol de cadenes.

Compte: toupper() només funciona bé amb lletres sense accent (a-z). Amb vocals accentuades com "ó" dona resultats estranys, perquè en UTF-8 ocupen més d'un byte — per això l'exemple fa servir "amic" i no una paraula accentuada.

Exercicis d'autoavaluació

Aquests es generen amb valors nous a l'atzar i tenen solució comprovable.

—

Quina serà la sortida per terminal d'aquest programa?