Problema programma in C!

di il
2 risposte

Problema programma in C!

Salve a tutti. Mi è stato chiesto di scrivere un programma che, dati due file .txt contenenti dati, ne crei un terzo in cui riunisca tutti i dati in ordine crescente di data. Ora, il programma l'ho scritto e funziona, solo che si presenta un problema che non riesco a spiegare. In fase di scrittura ho creato una variabile FILE* f, che ho usato come controllo. Finito il programma ho cancellato tutte le istruzioni relative alla suddetta variabile (tant'è che quando compilo mi dà il warning: unused variable f), ma quando vado a cancellare la variabile stessa, il programma non funziona più, o, meglio, non stampa sul terzo file quello che dovrebbe stampare. Quindi, finchè lascio la viabile dichiarata, anche se non utilizzata, il programma lavora correttamente, mentre quando la cancello, smette di funzionare come dovrebbe. Riuscite a spiegarmi perchè? Grazie mille.
Ecco il codice:

#include <stdio.h>
#include <stdlib.h>

typedef struct
{
    int giorno;
    char a;
    int mese;
    char b;
    int anno;
} TipoData;

typedef struct
{
    float dato;
    TipoData data;
    int centralina;
} TipoDato;

void merge(TipoDato a[], int n, TipoDato b[], int m, TipoDato c[]);

int main()
{
    FILE* f1 = NULL, *f2 = NULL, *f3 = NULL, *f = NULL;
    TipoDato dati1[37], dati2[40], dati3[77];
    char a[11], b[12];
    int i=0, n=0, k=0;

    f1 = fopen("Dati1.txt","r");
    if (f1 == NULL)
    {
        printf("Errore nella lettura del file Dati1.txt!\n");
    }
    else
    {
        fscanf(f1,"%10s %11s",a,b);
        while (i<37)
        {
            fscanf(f1,"%f %d %c %d %c %d",&dati1[i].dato,&dati1[i].data.giorno,&dati1[i].data.a,
                                          &dati1[i].data.mese,&dati1[i].data.b,&dati1[i].data.anno);
            i++;
        }
        fclose(f1);
    }

    f2 = fopen("Dati2.txt","r");
    if (f2 == NULL)
    {
        printf("Errore nella lettura del file Dati2.txt!\n");
    }
    else
    {
        fscanf(f2,"%10s %11s",a,b);
        while (n<40)
        {
            fscanf(f2,"%f %d %c %d %c %d",&dati2[n].dato,&dati2[n].data.giorno,&dati2[n].data.a,
                                          &dati2[n].data.mese,&dati2[n].data.b,&dati2[n].data.anno);
            n++;
        }
        fclose(f2);
    }

    merge(dati1,37,dati2,40,dati3);

    f3 = fopen("Dati.txt","w");
    for (k=0;k<77;k++)
    {
        if (dati3[k].centralina == 1)
        {
            if (dati3[k].data.giorno >= 1 && dati3[k].data.giorno <= 9)
                fprintf(f3,"%.1f\t 0%d%c%d%c%d\t Centralina Milano02345\n",dati3[k].dato,dati3[k].data.giorno,dati3[k].data.a,
                                                                           dati3[k].data.mese,dati3[k].data.b,dati3[k].data.anno);
            else
                fprintf(f3,"%.1f\t %d%c%d%c%d\t Centralina Milano02345\n",dati3[k].dato,dati3[k].data.giorno,dati3[k].data.a,
                                                                          dati3[k].data.mese,dati3[k].data.b,dati3[k].data.anno);
        }
        else
        {
            if (dati3[k].data.giorno >= 1 && dati3[k].data.giorno <= 9)
                fprintf(f3,"%.1f\t 0%d%c%d%c%d\t Centralina Milano02346\n",dati3[k].dato,dati3[k].data.giorno,dati3[k].data.a,
                                                                           dati3[k].data.mese,dati3[k].data.b,dati3[k].data.anno);
            else
                fprintf(f3,"%.1f\t %d%c%d%c%d\t Centralina Milano02346\n",dati3[k].dato,dati3[k].data.giorno,dati3[k].data.a,
                                                                          dati3[k].data.mese,dati3[k].data.b,dati3[k].data.anno);
        }
    }

    if (f3 != NULL)
    {
        fclose(f3);
    }

    return 0;
}

void merge (TipoDato a[], int n, TipoDato b[], int m, TipoDato c[])
{
    int i=0,j=0,k=0;

    while (i <= n && j <= m)
    {
        if ((a[i].data.mese > b[j].data.mese) ||
            (a[i].data.mese == b[j].data.mese && a[i].data.giorno > b[j].data.giorno))
        {
            c[k].dato = b[j].dato;
            c[k].data.giorno = b[j].data.giorno;
            c[k].data.a = '/';
            c[k].data.mese = b[j].data.mese;
            c[k].data.b = '/';
            c[k].data.anno = b[j].data.anno;
            c[k].centralina = 2;
            j++;
        }
        else
        {
            c[k].dato = a[i].dato;
            c[k].data.giorno = a[i].data.giorno;
            c[k].data.a = '/';
            c[k].data.mese = a[i].data.mese;
            c[k].data.b = '/';
            c[k].data.anno = a[i].data.anno;
            c[k].centralina = 1;
            i++;
        }
        k++;
    }

    if (i <= n)
    {
        while (i <= n)
        {
            c[k] = a[i];
            c[k].centralina = 1;
            k++;
            i++;
        }
    }
    else
    {
        while (j <= m)
        {
            c[k] = b[j];
            c[k].centralina = 2;
            k++;
            j++;
        }
    }
}

2 Risposte

  • Re: Problema programma in C!

    Innanzitutto il controllo se è stato aperto il file f 3 va fatto subito dopo la Open, proprio come negli altri file.
    il problema sembra essere causato da un buffer overflow che in questo caso la s/fortuna vuole che non causi nessun crash.
    Da una svelta analisi dal telefono,hotel visto che il while nella funzione merge è sbagliato, dovrebbe essere i < n e j< m usando l'uguaglianza sfori dal vettore causando il buffer overflow.
  • Re: Problema programma in C!

    Grazie mille!! Il problema era effettivamente nell'uguaglianza e ho risolto. Ora funziona tutto perfettamente!
Devi accedere o registrarti per scrivere nel forum
2 risposte