Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Marvel's Wolverine, la recensione: Logan torna protagonista in un'avventura brutale e intensa
Marvel's Wolverine, la recensione: Logan torna protagonista in un'avventura brutale e intensa
Marvel's Wolverine porta Logan in un'avventura inedita, violenta e fortemente narrativa, costruita attorno alla sua natura di combattente e al difficile rapporto con il proprio passato. Insomniac Games punta su combattimenti spettacolari, progressione e personalizzazione, inserendo l'azione in un mondo segnato dalla persecuzione dei mutanti. Un viaggio intenso, che alterna mattanza, esplorazione e momenti sorprendentemente emotivi.
DJI Romo 2: tante novità lo rendono un robot completo
DJI Romo 2: tante novità lo rendono un robot completo
Romo 2 è la seconda generazione di robot lavapavimenti di DJI, un modello che si caratterizza per la precisione nel sistema di navigazione e per il funzionamento particolarmente silenzioso. Con le modifiche introdotte in questa seconda versione, e un posizionamento di prezzo più allineato alla concorrenza, rappresenta una valida alternativa sul mercato delle soluzioni di pulizia domestica
Sony Bravia 9 II: il True RGB alla prova, dove l'LCD sfida l'OLED
Sony Bravia 9 II: il True RGB alla prova, dove l'LCD sfida l'OLED
Il primo Sony con retroilluminazione True RGB alla prova del banco di misura e dei contenuti: luminanza enorme, colori accurati in HDR e un antiriflesso molto efficace. I limiti sono due sole HDMI 2.1 e il blooming fuori asse
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 10-08-2009, 21:34   #1
Y3PP4
Member
 
Iscritto dal: Jul 2009
Messaggi: 210
[C] Problema ciclo for dentro un ciclo while

Giorno,

sto facendo delle prove scrivendo un piccolo parser (niente di chè, solo escape di stringhe).
Attualmente ho messo a punto un algoritmo semplice semplice che prevede tramite un
while(!feof( fp )) la chiamata a varie funzioni, una delle quali è fgets.
Ottenuta la stringa poi passo tutto a un'altra funzione che tramite un ciclo for così definito:
Codice:
for( i=0; i<strlen( line ); i++ )
richiama continuamente uno switch(line[i]) e in seguito testa: se il carattere non è una tabulazione o spazio lo salva in un'altro puntatore e al termine del ciclo for ritorna la stringa.

Qui sorge il problema. Se provo a stampare le varie stringhe ottengo tutto con successo, ma ahimè l'ultima linea mi viene stampata due volte.

Qualcuno sà da cosa possa dipendere il problema?

Di seguito posto il problema semplificato (per non complicare le cose):
Codice:
// importo gli header necessari
void cleanString( char *line, char *escapedLine );
int main()
{
    // ... fp è argv[1]
    char line[500];
    char *escapedLine;
    while( !feof( fp ) )
    {
        fgets( line, sizeof( line ), fp );
       // alloco la memoria
        escapedLine = malloc ( strlen( line ) + 1 ) * ( sizeof( char ) ) );
        cleanString( line, escapedLine ); // 
        printf("%s\n", escapedLine);
        free( escapedLine );
    }
    return( EXIT_SUCCESS );
}
void
cleanString( char *line, char *escapedLine )
{
    unsigned int i;
    unsigned int a = 0; //  counter per cleanLine
    for( i=0; i<strlen( line ); i++ )
    {
        switch( line[i] )
        {
            case ' ' :
            case '\t':
            case '\n':
                break;
            default:
                cleanLine[a] = line[i];
                a++;
                break;
        }
    }
    return;
}
Questo è quanto.
Supponendo di avere un file con semplici frasi come potrebbe essere:
Giorno a tutti,
oggi mi sento
bene.

Ottengo come risultato:
Giornoatutti,
oggimisento
bene.
bene. <-- ripetuto due volte!

Grazie a tutti, buona notte.

Ultima modifica di Y3PP4 : 10-08-2009 alle 21:37.
Y3PP4 è offline   Rispondi citando il messaggio o parte di esso
Old 10-08-2009, 22:54   #2
DanieleC88
Senior Member
 
L'Avatar di DanieleC88
 
Iscritto dal: Jun 2002
Città: Dublin
Messaggi: 5989
Imposta il primo carattere della stringa a '\0' prima di leggere con fgets(), visto che è un buffer statico, dovrebbe bastare.

ciao
__________________

C'ho certi cazzi Mafa' che manco tu che sei pratica li hai visti mai!
DanieleC88 è offline   Rispondi citando il messaggio o parte di esso
Old 11-08-2009, 00:15   #3
Y3PP4
Member
 
Iscritto dal: Jul 2009
Messaggi: 210
Grazie mille per la risposta

Il sistema funziona (mi stampa solo un'ultima riga bianca ma dato che non dovrò stamparlo ed è un carattere nullo non dovrei avere problemi col parser...)

Come mai bisogna usare questo escape (o hack che dir si voglia) ?
Io avevo esplicitamente detto:
"mentre non incontri la fine del file -> leggi una riga -> leggi ogni carattere della riga -> se non è uno spazio mettilo da parte -> ritornami tutti i caratteri messi da parte -> stampa i caratteri ritornati"

Esegue palesemente un ciclo in più (in cui mi pare di capire che la stringa rimane inalterata) di quello richiesto...
inoltre perchè la stringa rimane immutata? non è dichiarata come static...

chiedo scusa ma alla solita se è possibile vorrei chiarire il concetto

Buona notte e mille grazie ancora!
Y3PP4 è offline   Rispondi citando il messaggio o parte di esso
Old 11-08-2009, 00:48   #4
nuovoUtente86
Senior Member
 
Iscritto dal: Mar 2007
Messaggi: 7863
effettua una prima fgets fuori dal while e posiziona la chiamata come ultima istruzione del while in modo da sincronizzare con feof la posizione sullo stream.
nuovoUtente86 è offline   Rispondi citando il messaggio o parte di esso
Old 11-08-2009, 07:12   #5
DanieleC88
Senior Member
 
L'Avatar di DanieleC88
 
Iscritto dal: Jun 2002
Città: Dublin
Messaggi: 5989
Quote:
Originariamente inviato da Y3PP4 Guarda i messaggi
Esegue palesemente un ciclo in più (in cui mi pare di capire che la stringa rimane inalterata) di quello richiesto...
inoltre perchè la stringa rimane immutata? non è dichiarata come static...
Perché finché non "fallisce" per la prima volta la fgets() non ti viene dato l'EOF, quindi l'ultimo ciclo sarà quello in cui la fgets() non avrà più niente da leggere. Il problema era che il tuo buffer era un'array dichiarata come variabile locale, che nasce e muore con la funzione in cui è stata dichiarata: al termine di ogni ciclo, i vecchi contenuti non vengono cancellati (al limite devi terminare tu a mano la stringa, come ti ho consigliato di fare io), e quindi nell'ultimo ciclo prima dell'EOF ottieni comunque la riga che già era dentro il buffer.
Alternativamente, puoi fare come consiglia nuovoUtente86 ed ottenere lo stesso effetto.

ciao
__________________

C'ho certi cazzi Mafa' che manco tu che sei pratica li hai visti mai!
DanieleC88 è offline   Rispondi citando il messaggio o parte di esso
Old 11-08-2009, 21:26   #6
Y3PP4
Member
 
Iscritto dal: Jul 2009
Messaggi: 210
Anzitutto mille grazie ad entrambi per la risposta.
Mille grazie nuovoUtente86 per il suggerimento, adesso che me lo hai esposto, tra l'altro, sembra la soluzione ad hoc al problema, mi sarà molto utile : grazie mille!

Quote:
Originariamente inviato da DanieleC88 Guarda i messaggi
Perché finché non "fallisce" per la prima volta la fgets() non ti viene dato l'EOF, quindi l'ultimo ciclo sarà quello in cui la fgets() non avrà più niente da leggere. Il problema era che il tuo buffer era un'array dichiarata come variabile locale, che nasce e muore con la funzione in cui è stata dichiarata: al termine di ogni ciclo, i vecchi contenuti non vengono cancellati (al limite devi terminare tu a mano la stringa, come ti ho consigliato di fare io), e quindi nell'ultimo ciclo prima dell'EOF ottieni comunque la riga che già era dentro il buffer.
ciao
Ancora una volta mi hai illuminato con una esposizione chiarissima: ti sono (nuovamente) debitore! Adesso mi è tutto chiaro;
soprattutto perchè dare il fine stringa al primo carattere prima dello fgets.
Grazie mille (inoltre mi sono chiarito anche il fatto che feof "cattura" un eof settato da un'altra funzione e non lo setta da solo).

Buona serata a tutti :-).
Y3PP4 è offline   Rispondi citando il messaggio o parte di esso
Old 11-08-2009, 22:07   #7
Y3PP4
Member
 
Iscritto dal: Jul 2009
Messaggi: 210
Uh, un'ultima cosa che mi era sfuggita.
Io dealloco la memoria con free(fp)... se libero la memoria contenente la stringa come fà ancora a restare in memoria nel ciclo successivo?

Solo una piccola curiosità



Buona serata,
ciao.
Y3PP4 è offline   Rispondi citando il messaggio o parte di esso
Old 11-08-2009, 22:46   #8
DanieleC88
Senior Member
 
L'Avatar di DanieleC88
 
Iscritto dal: Jun 2002
Città: Dublin
Messaggi: 5989
Perché la prendi da line e ce la ricopi dentro (la fgets() opera sulla line allocata staticamente, non sulla escapedString allocata dinamicamente).

ciao
__________________

C'ho certi cazzi Mafa' che manco tu che sei pratica li hai visti mai!
DanieleC88 è offline   Rispondi citando il messaggio o parte di esso
Old 11-08-2009, 23:00   #9
Y3PP4
Member
 
Iscritto dal: Jul 2009
Messaggi: 210
Quote:
Originariamente inviato da DanieleC88 Guarda i messaggi
Perché la prendi da line e ce la ricopi dentro (la fgets() opera sulla line allocata staticamente, non sulla escapedString allocata dinamicamente).

ciao
....

non ho parole: se mi scordo pure come funzionano gli algoritmi più semplici che scrivo pochi giorni prima, sarà meglio che ricorra ad una cura di fosforo.
Il fatto (a mia giustificazione ) è che nel programma uso un puntatore ad una sequenza di comandi (dichiarati come puntatori a funzione) per usare anzichè ad esempio fgets(...);
parser->getLine(...);

Beh che dire, dopo questa "svista" sarà meglio che con il prossimo post possa recuperare credito nel forum , magari chiedendo(ti) consiglio (o aiuto) su un algoritmo, quantomeno brillante.

Buona notte . (a mia giustificazione posso chiamare anche in causa l'ora? e la giornata in piscina?)
Y3PP4 è offline   Rispondi citando il messaggio o parte di esso
Old 11-08-2009, 23:07   #10
DanieleC88
Senior Member
 
L'Avatar di DanieleC88
 
Iscritto dal: Jun 2002
Città: Dublin
Messaggi: 5989
Lascia stare, non servono giustificazioni... c'è chi (io per primo) ha fatto e fa cose ben peggiori.

ciao
__________________

C'ho certi cazzi Mafa' che manco tu che sei pratica li hai visti mai!
DanieleC88 è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Marvel's Wolverine, la recensione: Logan torna protagonista in un'avventura brutale e intensa Marvel's Wolverine, la recensione: Logan torna p...
DJI Romo 2: tante novità lo rendono un robot completo DJI Romo 2: tante novità lo rendono un ro...
Sony Bravia 9 II: il True RGB alla prova, dove l'LCD sfida l'OLED Sony Bravia 9 II: il True RGB alla prova, dove l...
Geely EX5, un mese al volante: il SUV elettrico cinese che ci ha sorpreso (quasi) senza riserve Geely EX5, un mese al volante: il SUV elettrico ...
Mova Z70 Ultra Roller Complete: motore potente, rullo di lavaggio e l'IA a guidare Mova Z70 Ultra Roller Complete: motore potente, ...
La Serie A con DAZN e Amazon Prime con l...
Giochi Ubisoft su Steam senza Ubisoft Co...
Miami Beach ha autorizzato la maxi opera...
Apple regala un altro anno di funzioni s...
Alla fine è successo davvero: Vol...
Il meglio di Amazon del weekend in uno s...
Speciale TV in offerta su Amazon: Hisens...
Non c'è pace per Trezor: 347.000 e-mail ...
È un portatile Dell e li vale tut...
Apple iPhone 17 Pro Max 256GB a 1.195€ (...
GPT-6 Astra è davvero AGI o non s...
LG OLED G6S 48'' a 845€ e G6 55'' a 1368...
Mantax Otax: il malware Android che crip...
Musk incassa un altro maxi contratto IA:...
Le vendite di EV sono esplose in tutto i...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 22:43.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Served by www3v