PDA

Visualizza la versione completa : [C/C++]Domanda su fgets


Marco1995
31-03-2013, 14:10
Ciao ragazzi e buona pasqua :D .

Premetto che ho letto la documentazione di fgets ma non trovo ci che fa al caso mio.

Ovvero:


On success, the function returns str.
If the end-of-file is encountered while attempting to read a character, the eof indicator is set (feof). If this happens before any characters could be read, the pointer returned is a null pointer (and the contents of str remain unchanged).
If a read error occurs, the error indicator (ferror) is set and a null pointer is also returned (but the contents pointed by str may have changed).

Qui mi sembra parli solo dell'eventuale occorrenza della fine del file...ma come faccio a controllare che la funzione non vada in "buffer overflow" ,ovvero come faccio a controllare che il buffer sia sufficentemente capiente?
Ad esempio:


int main()
{
char parola[5];

do{
cout << "Inserisci la parola da testare ";
fgets(parola,5,stdin);
if(//Non so la condizione)
cout << "Buffer overflow ";
}
while(non so la condizione);



Come condizione ho provato a metterci ferror(stdin) ma non funziona..anche perch questo bit si setta solo se c' stato un errore di lettura...e questo non un errore di lettura :dh:

Grazie delle risposte :zizi:

oregon
31-03-2013, 15:27
Forse non ti ho capito ma dato che hai letto la documentazione ti chiedo ... a cosa serve il secondo parametro ?

Kaamos
31-03-2013, 15:45
Originariamente inviato da Marco1995
Ciao ragazzi e buona pasqua :D .

Premetto che ho letto la documentazione di fgets ma non trovo ci che fa al caso mio.

Ovvero:

Qui mi sembra parli solo dell'eventuale occorrenza della fine del file...ma come faccio a controllare che la funzione non vada in "buffer overflow" ,ovvero come faccio a controllare che il buffer sia sufficentemente capiente?
Ad esempio:


int main()
{
char parola[5];

do{
cout << "Inserisci la parola da testare ";
fgets(parola,5,stdin);
if(//Non so la condizione)
cout << "Buffer overflow ";
}
while(non so la condizione);



Come condizione ho provato a metterci ferror(stdin) ma non funziona..anche perch questo bit si setta solo se c' stato un errore di lettura...e questo non un errore di lettura :dh:

Grazie delle risposte :zizi:

Il buffer overflow letteralmente non si verifica mai visto fgets si "ferma" prima (assumendo ovviamente che tu le passi il giusto secondo parametro), se intendi verificare che sia stata letta l'intera linea, visto che uno stream di testo presumibilmente una sequenza di stringhe con un terminatore di linea alla fine puoi controllare se la stringa letta finisce col suddetto terminatore.

Comunque c' qualche motivo particolare per cui usi le funzioni del C in C++? C' la libreria iostream e le std::string da usare...

Marco1995
31-03-2013, 17:23
Forse non ti ho capito ma dato che hai letto la documentazione ti chiedo ... a cosa serve il secondo parametro ?
Il secondo parametro serve a specificare la dimensione del buffer per non sforare.Il problema che non so come "far accorgere" il programma che stato "oltrepassato" lo spazio limite.


se intendi verificare che sia stata letta l'intera linea, visto che uno stream di testo presumibilmente una sequenza di stringhe con un terminatore di linea alla fine puoi controllare se la stringa letta finisce col suddetto terminatore.
Se ti riferisci al '\0' ammesso che controlli se la stringa letta finisce col terminatore...non ho la certezza che la stringa sia stata letta interamente,dato che la funzione "legge quello che pu leggere" e poi ci piazza il terminatore alla fine,o sbaglio? :confused:


Comunque c' qualche motivo particolare per cui usi le funzioni del C in C++? C' la libreria iostream e le std::string da usare...
No,non c' nessun motivo particolare,ma dato che ho sempre usato le librerie e le funzioni del C, mi sono abituato con quelle(apparte cout e cin che sono troppo comode :D)

oregon
31-03-2013, 17:35
Originariamente inviato da Marco1995
Il secondo parametro serve a specificare la dimensione del buffer per non sforare.

Quindi, perch ti chiedi come evitare gli overflow?


Il problema che non so come "far accorgere" il programma che stato "oltrepassato" lo spazio limite.

Continuo a non capire. Non se ne deve occupare il tuo programma ... la fgets che non lo oltrepassa ...

Marco1995
31-03-2013, 18:00
Continuo a non capire. Non se ne deve occupare il tuo programma ... la fgets che non lo oltrepassa ...

Esempio:


int main()
{
int i;
char parola[5];
fgets(parola,5,stdin);
for(i=0;i<strlen(parola);i++)
if(parola[i] != parola[strlen(parola)-i-1])
break;

if(i==strlen(parola))
cout << "Palindroma";
else
cout << "Non palindroma";
}

Al di l del codice banale buttato gi in 2 secondi...se io metto "anna" ok,la parola palindroma...ma se metto "annaciao" la parola palindroma lo stesso perch giustamente la fgets tronca le parti in eccesso.
Io vorrei fare in modo che la fgets mi riconoscesse questo caso. (quando il buffer minore della lunghezza della parola).
Altro esempio:


void StampaContrario(char parola[],int indice);
int main()
{
char parola[5];
cout << "Inserisci la parola ";
fgets(parola,5,stdin);

StampaContrario(parola,0);
return 0;
}
void StampaContrario(char parola[],int indice)
{
if (parola[indice+1]=='\0')
return;

StampaContrario(parola,++indice);
cout << parola[indice];
if(indice==1)
cout << parola[0];

}

Se do in input annaciao...in output ottengo solamente anna;se addirittura faccio cos:


if (parola[indice+1]=='\n')
return;


ottengo una lunga sequenza di caratteri casuali..

MItaly
31-03-2013, 18:44
Se l'ultimo carattere della stringa ottenuta non un '\n' c' stato un troncamento.


char str[256];
fgets(str, sizeof(str), stdin);
if(str[strlen(str)-1]!='\n')
{
// c' stato troncamento
}

Marco1995
31-03-2013, 18:53
Se l'ultimo carattere della stringa ottenuta non un '\n' c' stato un troncamento.



char str[256];
fgets(str, sizeof(str), stdin);
if(str[strlen(str)-1]!='\n')
{
// c' stato troncamento
}


Proprio questo mi serviva!!Forse prima mi ero espresso male..ma hai centrato in pieno il mio problema :D


Se l'ultimo carattere della stringa ottenuta non un '\n' c' stato un troncamento.

Non dovremmo parlare di *penultimo* carattere della stringa?L'ultimo dovrebbe essere sempre il carattere terminatore '\0' . . :confused:

MItaly
31-03-2013, 19:01
Originariamente inviato da Marco1995
Proprio questo mi serviva!!Forse prima mi ero espresso male..ma hai centrato in pieno il mio problema :D

Non dovremmo parlare di *penultimo* carattere della stringa?L'ultimo dovrebbe essere sempre il carattere terminatore '\0' . . :confused:
Questione di gusti... mi piace pensare che il \0 sia "uno dopo l'ultimo" (in altri termini, serve a terminare la stringa, ma concettualmente non "davvero" parte della stringa - strlen, ad esempio, non lo conta).
Vedila cos: "" una stringa di lunghezza 0, anche se in realt un array di char contenente solo '\0' in prima posizione.

... poi comunque l'importante intendersi.

totzi
31-03-2013, 19:05
il penultimo.

Loading