PDA

Visualizza la versione completa : [C] Lettura e riconoscimento di comandi


Dimitree88
05-01-2012, 12:00
ciao a tutti :)
sto scrivendo un piccolo programma in C che iterativamente resta in attesa di un comando da stdin. I comandi sono codificati come stringhe tipo "start" "delete" ecc, e se riconosciuti eseguono determinate operazioni. Quello che non so come realizzare è il riconoscimento di alcuni comandi tipo "comando [opzione]" dove la parte tra [] è opzionale, e in caso ci sia va memorizzata.
Per il riconoscimento dei comandi ho semplicemente messo una serie di if/else if che confrontano la stringa letta. Come posso fare?
grazie!

Beavey
05-01-2012, 12:49
Ciao,
quello che puoi fare e' riconoscere gli spazi all'interno dell'array di caratteri (immagino che la tua stringa sia un array di caratteri, visto che lavori in C) e separare la tua stringa di input in termini di questi: quindi 'leggi' la stringa di input fino a trovare o meno uno spazio. Tutti i caratteri prima dello spazio sono il <comando> mentre tutto quello che viene dopo (se esiste) sono le opzioni.

Mettiamo che hai separato una stringa di comandi e opzioni. A questo punto usi i tuoi if/else statements per riconoscere se il comando e' uno valido, dopodiche', se un comando ha anche opzioni, cerchi di riconoscere se le opzioni inserite dallo user sono valide.

In C++ potresti usare la classe String e potresti separare il comando e le opzioni utilizzando ricorsivamente String::find() per trovare le posizioni di spazi, se esistono, e substr, per 'tagliare' la stringa a quelle posizioni.

Spero di essere stato d'aiuto!

EDIT:

P.S. Vedi (sono in inglese pero'):
http://www.cplusplus.com/reference/string/string/substr/
http://www.cplusplus.com/reference/string/string/find/

Dimitree88
06-01-2012, 16:23
ti ringrazio molto

ho provato intanto a riconoscere comandi semplici ma ho già prime difficoltà:



int main ()
{
char* cmd;

while(1) {

scanf("%s", &cmd);

if (!(strcmp(&cmd, "start"))) {
start();
}
else if (!(strcmp(&cmd, "stop"))) {
return 0;
}
else {
printf("Comando non riconosciuto\n");
}
}

return 0;
}


a parte che ricevo questi warning dal compilatore gcc (su ubuntu):

alla linea di scanf:
"format '%s' expects type 'char *', but argument 2 has type 'char **' "

alle linee dove uso strcmp
"passing argument 1 of 'strcmp' from incompatible pointer type"

ma oltre a questo, ottengo un segmentation fault alla chiusura del programma se digito comandi di lunghezza maggiore a 3 caratteri.
tuttò ciò è sicuramente dovuto alla mia ignoranza in materia di scanf e puntatori, quindi sapreste correggermi o darmi un indizio? :)
vi ringrazio ancora

ramy89
06-01-2012, 17:02
Correggilo così:


int main ()
{
char *cmd;
cmd=(char*)malloc(100*sizeof(char));
while(1) {

scanf("%s", cmd);

if (!(strcmp(cmd, "start"))) {
start();
}
else if (!(strcmp(cmd, "stop"))) {
return 0;
}
else {
printf("Comando non riconosciuto\n");
}
}

return 0;
}

ramy89
06-01-2012, 17:08
Per quanto riguarda le opzioni dei comandi, ti consiglio di usare uno stack di stringhe.
Ogni volta che leggi una porzione di stringa racchiusa tra parentesi pushi nello stack quella stringa.
Ad esempio se hai il comando:


do [opzione1] [opzione2]

Leggi tutta la stringa, innanzitutto controlli che ogni simbolo '[' sia seguito da un simbolo ']', ma quello lo fai a parte.Dopo il controllo dividi la stringa in 3 parti:


"do"
"[opzione1]"
"[opzione2]"

L' hai divisa in token.
Una volta divisa hai le varie parti inserite nello stack, ti basterà leggerlo.
Stai scrivendo il programma di un interprete comandi, in particolare la parte che divide la stringa in token è l' analizzatore lessicale.

Eleviolet
08-01-2012, 15:14
edit

Dimitree88
08-01-2012, 15:16
grazie
e come dovrei implementare questo stack? come un array di char* ?
che funzioni posso usare per le operazioni che mi hai consigliato? ci sono funzioni per stringhe nella libreria standard oppure devo fare tutto a mano?

ramy89
08-01-2012, 15:31
edit

ramy89
08-01-2012, 15:50
Puoi fare una lista linkata contenente array di char,ma se non ti va di implementare la lista potresti anche tenere tutto sullo stesso array di char.
In string.h c'è la funzione strtok (http://www.cplusplus.com/reference/clibrary/cstring/strtok/) per suddividere una stringa in token.Basta specificare il delimitatore, ti faccio un esempio:


char *str;
char *tokens;
// allochi spazio per le stringa e prendi str in input
tokens=strtok(str," []");

In pratica ti divide la stringa ogni volta che incontra uno spazio, o un carattere '[' , o ']'.Quei caratteri verranno poi eliminati dalla stringa, per cui ora hai direttamente i comandi su cui lavorarci sopra.

Dimitree88
15-01-2012, 16:55
grazie ancora, funziona alla grande
manca solo il controllo del matching delle [ ]
devo farlo "a mano" analizzando carattere per carattere oppure c'è qualche funzione di libreria? io nn ne ho trovate

Loading