Funzioncina per il controllo dell'input

Stefanokj

Utente Attivo
333
7
OS
Arch
Ciao ragazzi, dovrei realizzare due funzioni molto simili ma ho dei problemi.

1) Devo leggere la stringa "Nome", questa stringa può contenere solo lettere (maiuscole e minuscole) e spazi.
2) Devo leggere la stringa "Key", questa stringa può contenere solo lettere (maiuscole e minuscole) e numeri (nessuno spazio).

Se le linee guida non vengono seguite, l'utente deve essere in grado di poter rifare l'input.
Sfortunatamente, non posso usare librerie speciali (solo stdio e stdlib).
Questo è quello che ho fatto:
C:
    void checkString(char *i){
        int cont;
        do {
            scanf("%s", i);
            if (checkStrLen(6, 6, i) != 0) { //controllo lunghezza stringa (min,max,stringa)
                for(cont=0; cont<6;){  
                    if((i[cont]>='0' && i[cont]<='9')||
                      (i[cont]>='A' && i[cont]<='Z')||
                      (i[cont]>='a' && i[cont]<='z')){
                        cont++;
                    }else{
                        printf("Not valid character");
                        printf("Try again"); break;
                    }
            }
        }else{
            printf("\nToo large string");
            printf("\nTry again"); break;
        }
    }while(1);
}
Stavo pensando di fare qualcosa di simile.
Per il primo problema sostituirei
Codice:
(i [cont]> = '0' && i [cont] <= '9')
con
Codice:
(i [cont] == ' ')
.
Purtroppo non funziona, e non capisco dove sto sbagliando.
Inoltre non so come realizzare il for, nel caso di "Key" la lunghezza ammessa è di 16 caratteri (non più e non meno), mentre per il nome ho la lunghezza massima che è 64 (ma posso avere anche meno).
Mi potreste dare una mano?
 

pabloski

Utente Èlite
2,868
916
Beh trovo spaventoso che passi il buffer della stringa a checkString e poi faccia lo scanf nella funzione. Potresti andare incontro ad un buffer overflow.

Non mi è chiaro perchè checkStrLen. Non basta strlen?? La specifica parli di lunghezza massima, perchè fissarsi sulla minima?

Inoltre non vedo la } del for. Il che è un errore di sintassi.

Infine perchè il for cicla sempre tra 0 e 5? Se la stringa è 10 caratteri che fa? Guarda i primi 6 e gli altri 4 li lascia perdere?
 

Stefanokj

Utente Attivo
333
7
OS
Arch
1)Beh trovo spaventoso che passi il buffer della stringa a checkString e poi faccia lo scanf nella funzione. Potresti andare incontro ad un buffer overflow.

2)Non mi è chiaro perchè checkStrLen. Non basta strlen?? La specifica parli di lunghezza massima, perchè fissarsi sulla minima?

3)Inoltre non vedo la } del for. Il che è un errore di sintassi.

4)Infine perchè il for cicla sempre tra 0 e 5? Se la stringa è 10 caratteri che fa? Guarda i primi 6 e gli altri 4 li lascia perdere?
1)Come dovrei fare allora? Per ora ho utilizzato questo metodo anche in altre funzioni e non ho avuto problemi ( dopo ogni funzione che richiede un input di stringa metto uno svuotabuffer())
2)checkstrlen non è altro che uns strlen che restituisce la lunghezza solo se è compresa tra min e max, mi fisso sulla minima perchè una stringa vuota non deve essere accettata.
3) è nella riga 15, subito prima del secondo else
4) si, questo lo dovrei correggere, l'ho lasciato così perchè nel caso di "Key" sono sicuro che la stringa sia di 16 (se no, non devo accettarla), invece in caso di "Nome" so solo che accetto al max 64 caratteri, quindi dovrei metterci il valore restituito da strlen
 

M1n021

Nuovo Utente
143
68
Ciao, innanzitutto la funzione checkString() secondo me deve limitarsi a ritornare un intero che ci dice se la stringa è valida e segue le specifiche; sarà poi il main(), valutando il valore ritornato dalla suddetta funzione, a chiedere eventualmente un nuovo input.

Inoltre ti faccio notare che risulta superfluo scorrere due volte la stringa (la prima con checkStrLen()), riflettici!

Volendo implementare un'unica funzione più generica, che vada bene sia per Nome che per Key, potresti ricorrere ad un prototipo del genere:;
C:
int check_string(const char *str, const unsigned int min, const unsigned int max, const int flag_digit, const int flag_space);

Infine vale la pena sottolineare che con lo specificatore %s la scanf() si arresta al primo carattere whitespace.
 

pabloski

Utente Èlite
2,868
916
1)Come dovrei fare allora? Per ora ho utilizzato questo metodo anche in altre funzioni e non ho avuto problemi ( dopo ogni funzione che richiede un input di stringa metto uno svuotabuffer())

funziona, ma è facilmente trasformabile in un problema di sicurezza...se si tratta di programmi per esercizio va bene anche così

2)checkstrlen non è altro che uns strlen che restituisce la lunghezza solo se è compresa tra min e max, mi fisso sulla minima perchè una stringa vuota non deve essere accettata.

il punto è che una stringa vuota non eseguirebbe nemmeno un'iterazione di quel for, per cose sarebbe automaticamente non considerata

3) è nella riga 15, subito prima del secondo else

visto, è l'indentazione che trae in inganno

4) si, questo lo dovrei correggere, l'ho lasciato così perchè nel caso di "Key" sono sicuro che la stringa sia di 16 (se no, non devo accettarla), invece in caso di "Nome" so solo che accetto al max 64 caratteri, quindi dovrei metterci il valore restituito da strlen
 

Stefanokj

Utente Attivo
333
7
OS
Arch
funziona, ma è facilmente trasformabile in un problema di sicurezza...se si tratta di programmi per esercizio va bene anche così
A proposito di sicurezza se posso, volevo chiederti una cosa, devo fare una funzione che genera un indirizzo casuale.
Siccome generare una stringa casuale mi sembrava brutto ho deciso di generare un numero, e con uno switch assegnarli la città e la via + un numero casuale tra 0 e 999 per il civico.
Questo è il codice: https://pastebin.com/XRtaAhtL
Secondo te va bene? Non ci sono problemi per quanto riguarda il funzionamento, però essendo una funzione che va in un progetto non dico grande ma, abbastanza sostanzioso, ho paura che incasini la memoria, perchè non ho mai usato strcpy e sprintf
 

pabloski

Utente Èlite
2,868
916
A proposito di sicurezza se posso, volevo chiederti una cosa, devo fare una funzione che genera un indirizzo casuale.
Siccome generare una stringa casuale mi sembrava brutto ho deciso di generare un numero, e con uno switch assegnarli la città e la via + un numero casuale tra 0 e 999 per il civico.
Questo è il codice: https://pastebin.com/XRtaAhtL
Secondo te va bene? Non ci sono problemi per quanto riguarda il funzionamento, però essendo una funzione che va in un progetto non dico grande ma, abbastanza sostanzioso, ho paura che incasini la memoria, perchè non ho mai usato strcpy e sprintf

Non ci vedo niente di strano. Magari usare degli array al posto degli switch sarebbe più semplice e pulito.
 

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!