• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Zapis do pliku binarnego C ANSI PEDANTIC WALL

VPS Starter Arubacloud
0 głosów
792 wizyt
pytanie zadane 18 maja 2020 w C i C++ przez Daim123 Użytkownik (530 p.)

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).

Mam problem, ponieważ do pliku zapisuje się jedynie liczba liczb w linii i nie wiem jak to naprawić. 

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

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

int number_of_numbers(char * 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;
    char *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 = (char*)malloc(sizeof(char)*lSize);
   
    while(fgets(r.arr,lSize,f)!=NULL)
   {
       r.num = number_of_numbers(r.arr);
       fwrite(&r, sizeof(struct rec), sizeof(r.arr), f_2);
   }
  
 
    fclose(f);
    free(r.arr);
    fclose(f_2);
    return 0;
}

 

1 odpowiedź

0 głosów
odpowiedź 19 maja 2020 przez j23 Mędrzec (195,220 p.)

Zapis pojedynczej linii tak powinien wyglądać:

float* p = /* tablica floatów */;
size_t n = /* ilość liczb w 'p' */;

fwrite(&n, sizeof(size_t), 1, f_2);
fwrite(p, sizeof(float), n, f_2);

 

komentarz 20 maja 2020 przez Daim123 Użytkownik (530 p.)
A gdybym chciał zrobić to w drugą stronę, teraz ten plik co zapisałem jakbym chciał go otworzyć i zapisać do normalnego?
komentarz 20 maja 2020 przez j23 Mędrzec (195,220 p.)

Robisz odwrotnie. Użyj funkcji fread i fprintf.

komentarz 20 maja 2020 przez Daim123 Użytkownik (530 p.)
w sensie, że zamiast fwrite, fread?
komentarz 21 maja 2020 przez Daim123 Użytkownik (530 p.)

       fread(&r.num, sizeof(size_t), 1, f);
       fread(r.arr, sizeof(float), r.num, f);
       
    for(i=0; i<r.num; i++) fprintf(f_2,"%f ", r.arr[i]);

Tylko nie wiem w w jakiej pętli to zamknąć, z jakim warunkiem i jak poradzić sobie  z zapisem np 3.00000

komentarz 21 maja 2020 przez j23 Mędrzec (195,220 p.)
edycja 21 maja 2020 przez j23
struct rec r = { 0, NULL };

while (fread(&r.num, sizeof(size_t), 1, f) == 1) {
	r.arr = realloc(r.arr, sizeof(float) * r.num);
	r.num = fread(r.arr, sizeof(float), r.num, f);
	for(i = 0; i < r.num; i++) 
		fprintf(f_2, "%g ", r.arr[i]);
}

free(r.arr);

 

Podobne pytania

0 głosów
1 odpowiedź 376 wizyt
pytanie zadane 16 marca 2020 w C i C++ przez Quanti994 Początkujący (340 p.)
0 głosów
1 odpowiedź 555 wizyt
pytanie zadane 2 grudnia 2018 w C i C++ przez MAXIM7 Obywatel (1,990 p.)
0 głosów
1 odpowiedź 1,764 wizyt
pytanie zadane 6 lutego 2019 w C i C++ przez kamasazi98 Początkujący (410 p.)

93,015 zapytań

141,978 odpowiedzi

321,271 komentarzy

62,358 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

Wprowadzenie do ITsec, tom 2

Można już zamawiać tom 2 książki "Wprowadzenie do bezpieczeństwa IT" - będzie to około 650 stron wiedzy o ITsec (17 rozdziałów, 14 autorów, kolorowy druk).

Planowana premiera: 30.09.2024, zaś planowana wysyłka nastąpi w drugim tygodniu października 2024.

Warto preorderować, tym bardziej, iż mamy dla Was kod: pasja (użyjcie go w koszyku), dzięki któremu uzyskamy dodatkowe 15% zniżki! Dziękujemy zaprzyjaźnionej ekipie Sekuraka za kod dla naszej Społeczności!

...