Struktura która składa się z liczby całkowitej oraz tablicy liczb zmiennoprzecinkowych

0

**Mam takie polecenie: **

program otwiera plik tekstowy, którego każda linijka zawiera pewną, z góry nieokreśloną liczbę liczb
zmiennoprzecinkowych typu float (pełne rozwiązanie nie powinno zakładać żadnego ograniczenia na długość linijki),
odczytuje kolejne linijki i ich zawartość zapisuje do pliku binarnego jako rekordy o zmiennej długości:
każdy rekord składa się z liczby typu integer, która określa liczbę danych (liczb float) w linijce,
za którą następują same dane (liczby).
Plik nie powinien zawierać żadnych dodatkowych zapisów (separatorów, znaczników itp).

**I mam problem, ponieważ nie wiem jak stworzyć rekord, w sensie strukturę która będzie składała się z liczby całkowitej oraz z linijki tekstu. Liczbę całkowitą to wiadomo, ale nie wiem jak struktura ma przechowywać, bez ograniczeń linijkę tekstu. **

Bo gdyby nie to bez ograniczenia to coś takiego

struct rec{
int i;
float T[100000];

};
3

Albo używasz Flexible Array Member z C:

struct line
{
    size_t num;
    float[] arr;
};

Albo liczba + pointer:

struct line
{
    size_t num;
    float* arr;
};

W drugim przypadku wykonujesz dwie operacje zapisu, w pierwszym jedną, ale alokacja i dealokacja pamięci to ciut więcej obliczeń.

0

@kq: skorzystałem, na razie z pierwszego sposobu. na razie mój program wczytuje cały plik, nie wiem czy to dobrze, ale nie wiem jak przy pomocy funkcji fread wczytać samą linijkę bez ograniczeń. Mam funkcję która liczy ilość słów w linijce, oraz liczbę linii w programie, ale nie mam pomysłu co zrobić dalej.

#include <stdio.h>
#include <stdlib.h>
#define IN 1
#define OUT 0

struct rec
{
    int i;
    float T[];
};

int number_of_numbers(int i, char * buffer)
{
    int counter, state;
    
    counter = state = OUT;
    
    while((buffer[i]!='\n')&&(buffer[i]!=EOF))
    {
        if(buffer[i]==' '||buffer[i]=='\t') state = OUT;
        else if(state==OUT)
        {
            state = IN;
            counter++;
        }
        i++;
    }
    
    return counter;
}


int how_many_lines(char *buffer)
{
    int i,counter;
    
    i=0;
    counter = 1;
    while(buffer[i]!=EOF)
    {
        if(buffer[i]=='\n') counter++;
        i++;
    }
    
    return counter;
}


int main()
{
    FILE *f,*f_2;
   
    long lSize;
    char *buffer;
    struct rec r;
    size_t result;
    int i;

   
    
    i=0;
    f = fopen("plik.txt", "r");
    f_2=fopen("plikbinarny.txt", "wb");
    if(!f) return 1;
    
    fseek(f, 0, SEEK_END);
    lSize = ftell(f);
    rewind (f);
    
    buffer = (char*)malloc(sizeof(char)*lSize);
    
    result = fread(buffer,1, lSize, f);
    



 
    fclose(f);
    free(buffer);
    fclose(f_2);
    return 0;
}

0

Ale z pliku wejściowego masz wczytać dane w formacie tekstowym, czyli nie fread a fscanf.

0

@kq: Ten drugi sposób ma wyglądać jakoś tak?

struct rec
{
    size_t num;
    float *arr;
}
int main()
{
r.arr = (float*)malloc(sizeof(float)*lSize);

free(r.arr)
}
0

Tak, ale użyłbym znanego już r.num

0

czyli w sumie co muszę zmienić

0
#include <stdlib.h>
#define IN 1
#define OUT 0

struct rec
{
    size_t num;
    float *arr;
};

int number_of_numbers(float * buffer)
{
    int counter, state;
    int i;
   i=counter = state = OUT;
    
    while((buffer[i]!='\n')&&(buffer[i]!=EOF))
    {
        if(buffer[i]==' '||buffer[i]=='\t') state = OUT;
        else if(state==OUT)
        {
            state = IN;
            counter++;
        }
        i++;
    }
    
    return counter;
}




int main()
{
    FILE *f,*f_2;
   
    long lSize;
    float *buffer;
    struct rec r;


   
    f = fopen("plik.txt", "r");
    f_2=fopen("nowyplik.txt", "wb");
    if(!f) return 1;
    
    fseek(f, 0, SEEK_END);
    lSize = ftell(f);
    rewind (f);
    
    r.arr = (float*)malloc(sizeof(float)*lSize);
   
    while(fgets(r.arr,lSize,f)!=NULL)
   {
       r.num = number_of_numbers(r.arr);
       fwrite(&r, sizeof(struct rec), 1, f_2);
   }
  
 
    fclose(f);
    free(r.arr);
    fclose(f_2);
    return 0;
}


Jakaś mała podpowiedź?

0

Pierw wczytaj wszystko do tej struktury, a dopiero potem z niej zapisuj do pliku binarnego.

I musisz zaalokować pamięć dla r.arr

0

Czyli pierw wczytać sobie cały plik, ogarnąć ile ma linii i w pętli wpuścić wczytywanie z pliku do struktury przy pomocy

fscanf(f,"%d %f",r.num, r.arr[i])
``` ?
0

Nie ma potrzeby wielokrotnego przechodzenia po pliku. Po prostu każdą linię traktuj osobno.

Co ważne, dla każdej linii tylko raz wczytujesz liczbę elementów, a potem wczytuejsz tyle elementów ile ich w tej linii ma być.

0

Po prostu nie rozumiem, jak przy pomocy fscanf mam wczytywać linijkę tekstu, i skąd mam mieć ile jest liczb w linii zanim ją wczytam

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