Zliczanie liczby wierszy - problem

0

W pliku tekstowym mam dane liczby typu double w dwóch kolumnach z niewiadomą liczbą wierszy. Wszystko działa poprawnie, gdy używam do tego celu funkcji fgets, natomiast nie rozumiem dlaczego program wysypuje się w poniższym przypadku. Od czasu do czasu zadziała, kiedy przed funkcją rewind wpiszę printfa. Mógłby mi ktoś wyjaśnić dlaczego tak się dzieje?

Kod:

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

int cmp_r(const void *a, const void *b)
{
    return (*(double*)a - *(double*)b);
}

int cmp_m(const void *a, const void *b)
{
    return (*(double*)b - *(double*)a);
}

int main()
{
    int j,i=1,wiersze=0;
    char znak;
    FILE *fp;
    double *wsk1, *wsk2;
    fp = fopen("dane.txt", "r");
    if(!fp)
    {
        printf("Otwarcie pliku nie powiodlo sie \n");
        exit(-1);
    }

    while ( (znak = getc(fp)) != EOF) // Prawdopodobnie z ta petla jest jakis problem
    {
        if (znak == '\n')
            ++wiersze;
    }

    rewind(fp);
    
    wsk1 = (double *) malloc (wiersze * sizeof(double));
    wsk2 = (double *) malloc (wiersze * sizeof(double));

    fscanf(fp,"%lf", &wsk1[0]);
    fscanf(fp,"%lf", &wsk2[0]);
    
    while(feof(fp) == 0) 
    {
        fscanf(fp,"%lf", &wsk1[i]);
        fscanf(fp,"%lf", &wsk2[i]);
        i++;
    }

    printf("Tablica1    Tablica2\n");
    for(j=0;j<wiersze;j++)
    {
        printf("%6.2lf  %10.2lf \n", wsk1[j], wsk2[j]);
    }

    qsort(wsk1,wiersze,sizeof(double),cmp_r);
    qsort(wsk2,wiersze,sizeof(double),cmp_m);

    printf("\nTablice posortowane:\n\n");
    printf("Tablica1    Tablica2\n");
    for(j=0;j<wiersze;j++)
    {
        printf("%6.2lf  %10.2lf \n", wsk1[j], wsk2[j]);
    }

    free(wsk1);
    free(wsk2);
    fclose(fp);
    return 0;
}

 
0

zamień getc na fgetc.

0

Niczego to niestety nie zmienia.

0

Dobra, może uściślij słowo "wysypuje się"?

0

Kompiluje się, ale raz działa dobrze, raz się zapętla, innym razem wczyta poprawnie dane, ale tuż po tym wyskoczy błąd. Nie widzę nigdzie wycieku pamięci, nie mam pojęcia co może być nie tak. Przy funkcji fgets wszystko działało poprawnie, ale chcę zrozumieć ten problem.

0

a czy raz ostatni wiersz jest pusty, a raz nie?

0
  1. Źle sprawdzasz czy doszedłeś do końca pliku. Schemat ma być taki:
  • próba odczytania (fscanf, fgets czy co tam innego)
  • sprawdzamy, czy próba się powiodła (sprawdzamy co zwróciła funkcja wczytująca i/lub flagi na strumieniu - feof, ferror)
  • jeśli wszystko ok to dodajemy wczytany element do zbioru danych
  1. Źle podchodzisz do problemu. Na pamięci RAM operuje się szybciej niż na pamięci dyskowej. Dlatego zamiast najpierw liczyć linie w pliku a później wczytywać powinieneś zrobić to odwrotnie - wczytywać linie i zwiększać rozmiar bufora na liczby w miarę potrzeb:
  • wczytanie linii (fgets), przerywamy jeśli się nie udało
  • parsowanie linii (sscanf) wyciągając wartości double
  • zwiększenie rozmiaru bufora (tablicy z liczbami) np. dwukrotnie jeśli bufor jest już pełny
  • dodanie liczb do bufora
    i tak w kółko.

1 użytkowników online, w tym zalogowanych: 0, gości: 1