View Full Version : [C]Uso opzioni alfanumeriche "simil BASH"
Ciao a tutti ,
volevo sapere in che modo C può utilizzare opzioni alfanumeriche come per esempio fa in bash il comando cmp:
$ cmp -n2 file
dove in questo caso "-n" identifica l'opzione chiamata, e 2(che può essere qualsiasi intero chiamato da riga di comando a discrezione dell'utente) che permette di limitare l'opzione a 2 "elementi"
Io mi ritrovo in una situazione simile,in cui devo lanciare da riga di comando un programma C con un opzione che richiede un limitatore numerico.
La sitassi della riga è la seguente
$ ./prog -n arg1....argn
e in questo caso processa tutti gli argomenti
e devo arrivare ad avere
$ ./prog -nm arg1....argn
dove processa solo m argomenti
sono riuscito a implementare l'opzione attraverso la libreria <string.h> ma nn ho idea di come fare per implementare m,l'intero limitatore.
scusate se ho scritto qualche imprecisione ma al momento non ho il codice sotto mano e spero di essere stato il più chiaro possibile
DanieleC88
09-05-2009, 13:41
Leggi il parametro e vedi a quanto è impostato il limite massimo, poi per ogni argomento (che non è un'opzione) incrementi un contatore e confronti col limite: se lo hai superato, smetti di considerare gli argomenti.
aspetta, dopo che sono riuscito ad acquisirlo da riga di comando so come gestirlo, il problema è fargli prendere l'opzione
questo è il pezzo di codice interessato:
if ((strcmp(argv[2],"-lm")) == 0) { //strcmp è metodo di <string.h>
j=1;
for (i = c-1; i > 0; --i) {
if(j<m){
printf("Il %d numero e' = %d\n", j, array[i]);
++j;
}else{break;
}
}
}
dove array[] è un vettore di c elementi, non vuoto, definito in precedenza e m è il numero che gli passo da riga di comando
se io gli passo
$ ./prog -l5 arg1...argn
(in questo caso m=5)mi deve stampare gli elementi dell'array dall'ultimo al primo, bloccandosi quando arriva a m iterazioni
DanieleC88
09-05-2009, 15:15
In tal caso -lm non può funzionare, fai così:
Controlla che l'opzione inizi per -l (diciamo che la tua opzione è char *opzione = argv[i], con i l'indice dell'opzione che analizzi)
Scarta i primi due caratteri e controlla che l'opzione non si terminata (in altre parole, il puntatore alla stringa che ti interessa a quel punto è (opzione+2) - o, in modo equivalente, &opzione[2] - e devi controllare che non sia una stringa vuota)
Tenta la conversione da stringa a numero - a questo proposito non ti consiglio atoi() perché non rileva errori: ad esempio se la stringa fosse "10f" ti darebbe un 10; personalmente userei strtol() e controllerei che restituisse un puntatore NULL al secondo parametro.
Può sembrare un po' cervellotico ma credo sia la maniera più corretta di farlo (se non ti appoggi a routine esterne preconfezionate).
ciao ;)
DanieleC88
09-05-2009, 15:18
if ((strcmp(argv[2],"-lm")) == 0) { //strcmp è metodo di <string.h>
j=1;
for (i = c-1; i > 0; --i) {
if(j<m){
printf("Il %d numero e' = %d\n", j, array[i]);
++j;
}else{break;
}
}
}
Dimenticavo, i pezzi che ti ho evidenziato ti danno un tipico errore off-by-one (in quel modo di ciclare con la j effettui m-1 iterazioni, allo stesso modo in cui con la i effettui c-1 iterazioni), sostituisci il < con <= e il > con >=. ;)
questo è il mio codice modificato, spero come intendevi tu. Questa è un altra sezione del mio programma che in parole povere ordina in maniera crescente e si dovrebbe bloccare una volta che il la scansione dell'array arriva ad un numero maggiore del limite "-ln"
if ((strcmp(argv[1],"-l")) == 0) {
if(&argv[1][2]!=NULL){ //ho usato direttamente l'argomento
k=strtol(&(argv[1])[2],NULL,10);
sort(array, c);
for (i = 0; i < c; ++i) {
if(array[i]<=k){
printf("Il %d numero e' = %d\n", i + 1, array[i]);
}else{
free(array);
break;
}
}
free(array);
}
printf("limited!\n");/*LIMITED*/
}
e utilizzando sia l'atoi che il strtol ed entrambi non mi rilevano l'intero dopo "-l"e se ometto l'intero, l'output mi restituisce:
$./prog -l 7 6 4 9 0
Il 1 numero e' = 0
*** glibc detected *** ./cv: double free or corruption (fasttop): 0x08867008 ***
più altro....
DanieleC88
09-05-2009, 16:47
Aspetta, ci sono alcuni errori.
Innanzitutto lo strcmp() ad inizio blocco controlla se la stringa è esattamente quella, non se inizia per quella: usa strncmp() per confrontarne solo una porzione.
Poi, con il blocco:
if(&argv[1][2]!=NULL)
stai confrontando un char con NULL, che è un ((void*)0), e di certo non è quello che vuoi: confrontalo invece con '\0' (che è il terminatore di stringa).
Con questa riga:
k=strtol(&(argv[1])[2],NULL,10);
purtroppo non hai risolto molto, la chiamata è perfettamente equivalente ad atoi(), visto che passi un NULL al secondo parametro e la funzione non ha modo di informarti di un eventuale errore.
Io direi:
char *error;
n = strtol(stringaColNumero, &error, 10);
if (*error != '\0') /* ringrazio ||ElChE||88 per aver corretto la mia castroneria :D */
{
/* gestisci l'errore */
/* esci */
}
/* altrimenti usa il numero n */
Infine, cosa succede quando tu chiami free() ed esci dal for? C'è un altro free() identico lì ad aspettarlo... :D
Togli il free() prima del break. ;)
||ElChE||88
09-05-2009, 16:53
int main(int argc, char **argv)
{
long value;
char *end;
if (argc <= 1)
return 1;
if (strncmp(argv[1], "-l", 2) == 0)
{
value = strtol(argv[1] + 2, &end, 10);
if (*end != '\0')
{
printf("L'argomento e' nel formato sbagliato.\n");
}
else
{
printf("Il valore e': %ld.\n", value);
}
}
return 0;
}
DanieleC88
09-05-2009, 16:59
...
if (*end != '\0')
...
Hai ragionissima, errore mio.
DanieleC88
09-05-2009, 17:02
C'è rimasto da dire, a questo punto, che se strtol() restituisce 0 allora l'opzione è soltanto -l (senza numeri postfissi).
||ElChE||88
09-05-2009, 17:05
C'è rimasto da dire, a questo punto, che se strtol() restituisce 0 allora l'opzione è soltanto -l (senza numeri postfissi).
O -l0. :O
DanieleC88
09-05-2009, 17:08
O -l00000... Per quel che gli interessa non credo sia rilevante. :D
||ElChE||88
09-05-2009, 17:11
O -l00000... Per quel che gli interessa non credo sia rilevante. :D
Già... poi basta il più semplice degli if e si è a posto.
Una curiosità: ma l'indentazione usata da tookie esiste davvero? Perché mi fa un po' paura. :fagiano:
DanieleC88
09-05-2009, 17:14
Una curiosità: ma l'indentazione usata da tookie esiste davvero? Perché mi fa un po' paura. :fagiano:
Spero tanto di no, nessun editor sano di mente si sognerebbe di creargli un simile sfacelo... :D (a meno che non siano tabulazioni con una spaziatura personalizzata)
E ammetto che un po' paura la fanno anche a me. :eek:
ok grazie ragazzi, adesso mi funziona tutto perfettamente;-)
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.