RISOLTO Lettura di stringhe da file con fgets

Stato
Discussione chiusa ad ulteriori risposte.

Vito-

Utente Attivo
184
14
Ciao ragazzi, ho un file in cui ci sono scritte delle stringhe. Quando vado a leggere queste stringhe con fgets e poi con printf le stampo, l'ultima viene stampata 2 volte. Questo é il pezzo di codice

C:
void visualizza_record()
{
    printf("Ecco la lista dei tuoi Record:\n\n");
    ptrTuttiRecord = fopen("Lista_Record", "r");
    if(ptrTuttiRecord)
    {
        while(!feof(ptrTuttiRecord))
        {
            fgets(titoli, N, ptrTuttiRecord);
            printf("%s", titoli);
        }
    }
    else
    {
        printf("Errore di file");
    }
    fclose(ptrTuttiRecord);
 

DispatchCode

Moderatore
Staff Forum
Utente Èlite
2,223
1,854
CPU
Intel I9-10900KF 3.75GHz 10x 125W
Dissipatore
Gigabyte Aorus Waterforce X360 ARGB
Scheda Madre
Asus 1200 TUF Z590-Plus Gaming ATX DDR4
HDD
1TB NVMe PCI 3.0 x4, 1TB 7200rpm 64MB SATA3
RAM
DDR4 32GB 3600MHz CL18 ARGB
GPU
Nvidia RTX 3080 10GB DDR6
Audio
Integrata 7.1 HD audio
Monitor
LG 34GN850
PSU
Gigabyte P850PM
Case
Phanteks Enthoo Evolv X ARGB
Periferiche
MSI Vigor GK30, mouse Logitech
Net
FTTH Aruba, 1Gb (effettivi: ~950Mb / ~480Mb)
OS
Windows 10 64bit / OpenSUSE Tumbleweed
Il problema è la feof fatta in quel modo molto probabilmente. Dovresti usarla all'interno del ciclo, in un if, come vedi ad esempio qui https://www.tutorialspoint.com/c_standard_library/c_function_feof.htm

Ho cercato anche in rete ed in effetti è così. Questo è praticamente il tuo stesso problema https://stackoverflow.com/questions/1642789/fgets-in-c-repeats-last-line/47002678

C'è anche un errore nel tuo codice: fai una fclose anche se la fopen fallisce. fclose dovresti inserirlo nell'if, dopo il while.
Personalmente riscriverei però la funzione in questo modo:

C:
void visualizza_record()
{
    printf("Ecco la lista dei tuoi Record:\n\n");
    ptrTuttiRecord = fopen("Lista_Record", "r");
    if(!ptrTuttiRecord)
    {
        printf("Errore di file");
        return;
    }

    while(!feof(ptrTuttiRecord))
    {
        fgets(titoli, N, ptrTuttiRecord);
        printf("%s", titoli);
    }
    fclose(ptrTuttiRecord);
}

Il problema di questo feof usato così, è che fa quello che ti aspetti solo dopo l'ultimo fgetc (quindi fai un ciclo in più).
 

Vito-

Utente Attivo
184
14
Ti ringrazio, come sempre gentilissimo, ma
C:
while (true)
{
  fgets(buffer,100,soubor);
  if (feof(soubor))
    break;
  fputs (buffer , stdout);
}
fclose(soubor);
qui cosa vuol dire quel true nella condizione del while??
 

Tidus88

From another world
Utente Èlite
2,045
1,738
CPU
Ryzen 5600X
Dissipatore
Deepcool GAMMAX 400
Scheda Madre
Asus Prime B450-Plus
HDD
MX-500 500GB
RAM
Ballistix 16GB DDR4 3000Mhz
GPU
RTX 3060Ti Dual ASUS
Audio
Edifier R1280db
Monitor
Hisense H55U7A
PSU
Sharkoon Silentstorm Icewind 550W
Case
Corsair 275R Airflow White
Net
SkyWifi FTTH
OS
Windows 10
Ti ringrazio, come sempre gentilissimo, ma
C:
while (true)
{
  fgets(buffer,100,soubor);
  if (feof(soubor))
    break;
  fputs (buffer , stdout);
}
fclose(soubor);
qui cosa vuol dire quel true nella condizione del while??
Che cicla SEMPRE (praticamente è un ciclo infinito) finchè non arriva all'istruzione Break che lo fa uscire dal loop.
 

Andretti60

Utente Èlite
6,440
5,091
Più semplicemente
Codice:
while(fgets(titoli, N, ptrTuttiRecord) != NULL)
{
    printf("%s", titoli);
}
Questo perché il eof viene segnalato solo dopo avere fallito una lettura.
 
  • Mi piace
Reazioni: Vito-

Vito-

Utente Attivo
184
14
C:
printf("\n\nQuale record vuoi visualizzare?\nInserisci il titolo qui di seguito: ");
    getchar();
    gets(recordVisualizza);
    ptrFileRecord = fopen(recordVisualizza, "r");
    if(ptrFileRecord)
    {
        fgets(descrizione, M, ptrFileRecord);
        fgets(luogo, N, ptrFileRecord);
        fgets(amici, N, ptrFileRecord);
        fgets(orario, 6, ptrFileRecord);
        fgets(data, 11, ptrFileRecord);
        fclose(ptrFileRecord);
        printf("\nDescrizione: %s", descrizione);
        printf("\nLuogo: %s", luogo);
        printf("\nAmici: %s", amici);
        printf("\nOrario: %s\n", orario);
        printf("\nData: %s\n", data);
    }
    else
    {
        printf("Errore di file");
    }

Questo é il continuo della funzione che ho scritto sopra. Perché mi stampa tutto correttamente ma nell'ultimo printf dopo Data: non mette niente? E' come se non lo leggesse data
 

Andretti60

Utente Èlite
6,440
5,091
Controlla il valore di ritorno delle fgets(), se è NULL significa che c’è un errore di lettura e devi abortire l’operazione segnalando l’errore.
 

Andretti60

Utente Èlite
6,440
5,091
Devi controllare il valore di ritorno di ogni fgets() che usi. E come lo controlli? Con una istruzione if(), altrimenti con cosa?
 

Andretti60

Utente Èlite
6,440
5,091
Dipende da come è scritto il documento.
fscanf() e fgets() sono due funzioni differenti, quindi si comportano in maniera diversa. Per questo io continuo a battere sul chiodo: occorre sempre controllare il valore di ritorno delle funzioni, in caso di possibili errori.
 
  • Mi piace
Reazioni: Vito-
Stato
Discussione chiusa ad ulteriori risposte.

Ci sono discussioni simili a riguardo, dai un'occhiata!

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!

Discussioni Simili