Argumentele unei linii de comanda
In sistemul de calcul care admite limbajul C trebuie sa existe posibilitatea ca in momentul executiei unui program scris in acest limbaj sa i se transmita acestuia argumente sau parametri prin linia de comanda. Cind un program este lansat in executie si functia main este apelata, apelul va contine doua argumente. Primul argument (numit conventional argc) reprezinta numarul de argumente din linia de comanda care a lansat programul. Al doilea argument (argv) este un pointer la un masiv de pointeri la siruri de caractere care contin argumentele, cite unul pe sir.
Sa ilustram acest mod dinamic de comunicare intre utilizator si programul sau printr-un exemplu.
Fie programul numit pri care dorim sa imprime la terminal argumentele lui luate din linia de comanda, imprimarea facindu-se pe o linie, iar argumentele imprimate sa fie separate prin spatii.
Comanda:
pri succes colegi
va avea ca rezultat imprimarea la terminal a textului
succes colegi
Prin conventie, argv[0] este un pointer la numele pri al programului apelat, astfel ca argc, care specifica numarul de argumente din linia de comanda este cel putin 1.
In exemplul nostru, argc este 3, iar argv[0] argv[1] si argv[2] sint pointeri la 'pri' 'succes' si respectiv 'colegi'. Primul argument real este argv[1] iar ultimul este argv[argc-1]. Daca argc este 1, inseamna ca linia de comanda nu are nici un argument dupa numele programului.
Atunci programul pri are urmatorul cod:
main(int argc, char *argv[])
Deoarece argv este un pointer la un masiv de pointeri, exista mai multe posibilitati de a scrie acest program. Sa mai scriem doua versiuni ale acestui program.
main(int argc, char *argv[])
Deoarece argv este un pointer la un masiv de pointeri, incrementindu-l, (++argv), el va pointa la argv[1] in loc de argv[0]. Fiecare incrementare succesiva pozitioneaza pe argv la urmatorul argument, iar *argv este pointerul la argumentul sirului respectiv. In acelasi timp argc este decrementat pina devine zero, moment in care nu mai sint argumente de imprimat.
Alternativ:
main(int argc, char *argv[ ])
Aceasta versiune arata ca argumentul functiei printf poate fi o expresie ca oricare alta, cu toate ca acest mod de utilizare nu este foarte frecvent.
Ca un al doilea exemplu, sa reconsideram programul din sectiunea 7.5, care imprima fiecare linie a unui text care contine un sir specificat de caractere (schema).
Dorim acum ca aceasta schema sa poata fi modificata dinamic, de la executie la executie. Pentru aceasta o specificam printr-un argument in linia de comanda.
Si atunci programul care cauta schema data de primul argument al liniei de comanda este:
#define MAXLINE 1000
main(int argc, char *argv[ ])
unde linia de comanda este de exemplu: 'find limbaj' in care 'find' este numele programului, iar 'limbaj' este schema cautata. Rezultatul va fi imprimarea tuturor liniilor textului de intrare care contin cuvintul 'limbaj'
Sa elaboram acum modelul de baza, legat de linia de comanda si argumentele ei.
Sa presupunem ca dorim sa introducem in linia de comanda doua argumente optionale: unul care sa tipareasca toate liniile cu exceptia acelora care contin schema, si al doilea care sa preceada fiecare linie tiparita cu numarul ei de linie.
O conventie pentru programele scrise in limbajul C este ca argumentele dintr-o linie de comanda care incep cu un semn ' ' sa introduca un parametru optional. Daca alegem, de exemplu, -x pentru a indica „cu exceptia” si -n pentru a cere „numararea liniilor”, atunci comanda:
find -x -n la
avind intrarea:
la miezul stinselor lumini
s-ajung victorios,
la temelii, la radacini,
la maduva, la os.
va produce tiparirea liniei a doua, precedata de numarul ei, deoarece aceasta linie nu contine schema 'la'
Argumentele optionale sint permise in orice ordine in linia de comanda. Analizarea si prelucrarea argumentelor unei linii de comanda trebuie efectuata in functia principala main, initializind in mod corespunzator anumite variabile. Celelalte functii ale programului nu vor mai tine evidenta acestor argumente.
Este mai comod pentru utilizator daca argumentele optionale sint concatenate, ca in comanda:
find -xn la
Caracterele 'x' respectiv 'n' indica doar absenta sau prezenta acestor optiuni (switch) si nu sint tratate din punct de vedere al valorii lor.
Fie programul care cauta schema 'la' in liniile de la intrare si le tipareste pe acelea, care nu contin schema, precedate de numarul lor de linie. Programul trateaza corect, atit prima forma a liniei de comanda cit si a doua.
#define MAXLINE 1000
main(int argc, char *argv[])
if (argc!=1)
printf
('Nu exista argumente sau scheman');
else
while (getline(line,MAXLINE)>0)
}
}
Daca nu exista erori in linia de comanda, atunci la sfirsitul primului ciclu while argc trebuie sa fie 1, iar *argv contine adresa schemei. *++argv este un pointer la un sir argument, iar (*++argv)[0] este primul caracter al sirului. In aceasta ultima expresie parantezele sint necesare deoarece fara ele expresia inseamna *++(argv[0]) ceea ce este cu totul altceva (si gresit): al doilea caracter din numele programului. O alternativa corecta pentru (*++argv[0]) este **++argv
|