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

Wczytywanie do bufora kołowego

Object Storage Arubacloud
0 głosów
579 wizyt
pytanie zadane 2 kwietnia 2020 w C i C++ przez kaminie318 Bywalec (2,070 p.)
Witam. Czy jest ktoś wstanie wytłumaczyć jak wczytać dane do bufora kołowego omijając pierwszą linię pliku tekstowego w C? Mój plik w pierwszej linii zawiera napis rok i nazwy miesięcy natomiast w kolejnych wierszach są już konkretne wartości które chcę wczytać do bufora wierszami. Pół dnia szukam rozwiązań na internecie i nic, są implementacje bufora jednak nie wiem jak rozwiązać problem :/. Proszę o pomoc.
komentarz 2 kwietnia 2020 przez tkz Nałogowiec (42,000 p.)
Bufor kołowy/cykliczny, to rodzaj struktury, która ma stały rozmiar, a po jej przekroczeniu abstrakcyjny wskaźnik jest ustawiony na pozycję 0 w buforze.

Mówiąc trochę jaśniej. Mając tablice 10 elementową(od 0 do 9) wczytujemy dane do każdej komórki owej tablicy. Gdy bufor przekroczy 9, wskaźnik przeskoczy na pozycję 0.

0

0 1

0 1 2

0 1 2 3

0 1 2 3 4

0 1 2 3 4 5 6

0 1 2 3 4 5 6 7

0 1 2 3 4 5 6 7 8

0 1 2 3 4 5 6 7 8 9 // konczy się miejsce, zapętlamy

1 2 3 4 5 6 7 8 9 0

2 3 4 5 6 7 8 9 0 1

3 4 5 6 7 8 9 0 1 2

analogicznie dalej.
komentarz 3 kwietnia 2020 przez kaminie318 Bywalec (2,070 p.)
Znaczy samą ideę bufora raczej rozumiem, jednak nie mam pojęcia jak poradzić sobie z problemem. Nie wiem jak ominąć pierwszy wiersz zawierający datę i miesiące słownie, a następnie wczytywanie wierszami już dobrych wartości do bufora.
komentarz 3 kwietnia 2020 przez kaminie318 Bywalec (2,070 p.)

O kurcze, dziękuję bardzo! Teraz wpadłem na pomysł wczytywania danych do takiej struktury:

struct DaneZPliku
{
	int rok;
	float temp1;
	float temp2;
	float temp3;
	float temp4;
	float temp5;
	float temp6;
	float temp7;
	float temp8;
	float temp9;
	float temp10;
	float temp11;
	float temp12;
	float sredniaTeperatura;
	struct DaneZPliku*kolejneDane;
};

Tylko nie wiem jak to zaimplementować. Czy ten wskaźnik jak przy liście jednokierunkowej jest potrzebny ?

komentarz 3 kwietnia 2020 przez kaminie318 Bywalec (2,070 p.)

Mam coś takiego:

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

struct DaneZPliku
{
	int rok;
	float temp1;
	float temp2;
	float temp3;
	float temp4;
	float temp5;
	float temp6;
	float temp7;
	float temp8;
	float temp9;
	float temp10;
	float temp11;
	float temp12;
	float sredniaTeperatura;
};

struct DaneZPliku parser(FILE* plik) 
{
	struct DaneZPliku daneAktualne;

}

int main()
{
	FILE *plik;
	char znak;
	plik = fopen("plik.txt", "r");
	if(plik==NULL)
	{
		printf("Plik ktorego szukasz nie istnieje");
		exit(0);
	}
	char buffer[100];
	fgets(buffer, 100, plik);
	while (1)
	{
		znak = fgetc(plik); // czytanie z pliku
		if (znak == EOF)
		{
			break;
		}
		printf("%c", znak);
	}
}

Chce stworzyć parser który czyta te dane z pliku ale nie wiem jak zastąpić wpisywanie a pomocą istringstream w c;

komentarz 3 kwietnia 2020 przez tkz Nałogowiec (42,000 p.)

Dwa komentarze wyżej, nie jest to bufor kołowy...

struct circular_buf {
	uint8_t * buffer;
	size_t head;
	size_t tail;
	size_t max; //of the buffer
	bool full;
};

https://embeddedartistry.com/blog/2017/05/17/creating-a-circular-buffer-in-c-and-c/

1 odpowiedź

0 głosów
odpowiedź 2 kwietnia 2020 przez XxPPDKxX Obywatel (1,400 p.)
Pokaż w jaki sposób wczytujesz dane z pliku.
komentarz 3 kwietnia 2020 przez kaminie318 Bywalec (2,070 p.)

Mam praktycznie tylko otwarcie pliku, za wczytywanie do bufora mierszami od drugiego wiersza nie wiem jak się zabrać.

int main()
{
	FILE *plik;
	char znak;
	plik = fopen("plik.txt", "r");
	if(plik==NULL)
	{
		printf("Plik ktorego szukasz nie istnieje");
		exit(0);
	}
	while (1)
	{
		znak = fgetc(plik); // czytanie z pliku
		if (znak == EOF)
		{
			break;
		}
		printf("%c", znak);
	}
}

Dopiero startuję z nauką zwykłego c więc czuje się jak dziecko we mgle.

komentarz 3 kwietnia 2020 przez kaminie318 Bywalec (2,070 p.)

Zrobiłem jeszcze strukture na dane, jednak nie wiem jak to wszystko ze sobą scalić.

struct DaneZPliku
{
	int rok;
	float temp1;
	float temp2;
	float temp3;
	float temp4;
	float temp5;
	float temp6;
	float temp7;
	float temp8;
	float temp9;
	float temp10;
	float temp11;
	float temp12;
	float sredniaTeperatura;
	struct DaneZPliku*kolejneDane;
};

 

komentarz 3 kwietnia 2020 przez j23 Mędrzec (194,920 p.)

Pokaż przykładową linię z danymi. Teraz czytasz po znaku, co jest nieporozumieniem. Powinieneś użyć fscanf z odpowiednim format-stringiem.

komentarz 3 kwietnia 2020 przez kaminie318 Bywalec (2,070 p.)

To znaczy to czytanie znak po znaku było tylko wersją roboczą, gdyż chciałem zobaczyć czy plik w ogóle się wczytuje.Przykładowa linia z pliku:

1980 	-5.1 	0.5 	2.1 	6.3 	10.3 	15.6 	16.2 	16.6 	12.8 	8.9 	2.8 	0.7 	7.3

takie dane muszę wczytywać wierszami do bufora kołowego,aby potem wpisać do dwuwymiarowej tablicy dynamicznej. Myślałem o utworzeniu struktury na te dane(rok, temperaturę w każdym miesiącu) ponieważ gdzieś te dane muszę trzymać aby potem wpisać je do bufora, tak ? Jednak nie wiem jak wczytywać dane z pliku do struktury do separatora w c.

komentarz 3 kwietnia 2020 przez j23 Mędrzec (194,920 p.)
struct DaneZPliku record;

while (fscanf(file, "%u %f %f %f %f %f %f %f %f %f %f %f %f %f", 
		&record.rok,
		&record.temp1,
		&record.temp2,
		&record.temp3,
		&record.temp4,
		&record.temp5,
		&record.temp6,
		&record.temp7,
		&record.temp8,
		&record.temp9,
		&record.temp10,
		&record.temp11,
		&record.temp12,
		&record.sredniaTeperatura) == 14) {

	/* tu robisz coś z załadowanym recordem */
}

 

komentarz 3 kwietnia 2020 przez kaminie318 Bywalec (2,070 p.)
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>

#define BUF_SIZE 14

extern float buffer[BUF_SIZE];

struct DaneZPliku
{
	int rok;
	float temp1;
	float temp2;
	float temp3;
	float temp4;
	float temp5;
	float temp6;
	float temp7;
	float temp8;
	float temp9;
	float temp10;
	float temp11;
	float temp12;
	float sredniaTeperatura;
};

typedef struct {
	char* const buffer;
	uint8_t head;
	uint8_t tail;
} circ_buffer_t;

int8_t circ_buffer_put_char(circ_buffer_t* q, struct DaneZPliku record)
{
	uint8_t head_temp = q->head + 1;	
	
	if (head_temp == BUF_SIZE)
		head_temp = 0;

	if (head_temp == q->tail)
		return -1;

	q->buffer[head_temp] = ;	// Jak wpisać moją strukturę do bufora ??? 
	q->head = head_temp;			

	return 0;
}

int main()
{
	FILE *plik;
	char znak;
	plik = fopen("plik.txt", "r");
	if(plik==NULL)
	{
		printf("Plik ktorego szukasz nie istnieje");
		exit(0);
	}
	circ_buffer_t circBuff = { buffer, 0, 0 };
	char buffer[100];
	fgets(buffer, 100, plik);
	struct DaneZPliku record;
	while (fscanf(plik, "%u %f %f %f %f %f %f %f %f %f %f %f %f %f",
		&record.rok,
		&record.temp1,
		&record.temp2,
		&record.temp3,
		&record.temp4,
		&record.temp5,
		&record.temp6,
		&record.temp7,
		&record.temp8,
		&record.temp9,
		&record.temp10,
		&record.temp11,
		&record.temp12,
		&record.sredniaTeperatura) == 14) {


	}
}

Całość wygląda tak. Implementacje bufora znalazłem na internecie. Chciałbym dowiedzieć się jak wpisać wszystkie dane ze struktury do jednej szufladki w buforze. W przypadku jednej danej dałbym radę jednak moja struktura zawiera ich 14.

komentarz 3 kwietnia 2020 przez j23 Mędrzec (194,920 p.)

A ten bufor musi być buforem wartości typu char? Nie może być po prostu buforem wartości typu DaneZPliku (kiepska nazwa)?

komentarz 3 kwietnia 2020 przez kaminie318 Bywalec (2,070 p.)

Przerobiłem, chcę dane ze struktury wpisać do bufora a następnie zapisać do tablicy dynamicznej, ale nie cały czas coś nie gra.

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

#define BUF_SIZE 14

extern float buffer[BUF_SIZE];

struct DaneZPliku
{
    int rok;
    float temp1;
    float temp2;
    float temp3;
    float temp4;
    float temp5;
    float temp6;
    float temp7;
    float temp8;
    float temp9;
    float temp10;
    float temp11;
    float temp12;
    float sredniaTeperatura;
};

typedef struct {
    struct DaneZPliku * buffer;
    uint8_t head;
    uint8_t tail;
} circ_buffer_t;

int8_t circ_buffer_put_char(circ_buffer_t* q, struct DaneZPliku record)
{
    uint8_t head_temp = q->head + 1;    
    
    if (head_temp == BUF_SIZE)
        head_temp = 0;

    if (head_temp == q->tail)
        return -1;

    q->buffer[head_temp]=record;    // Jak wpisać moją strukturę do bufora ??? 
    q->head = head_temp;            

    return 0;
}

int8_t circ_buffer_get_char(circ_buffer_t* q)
{
    int wiersze, kolumny;
    int** tab;
    printf("Wiersze: ");
    scanf("%d", wiersze);
    printf("Kolumny: ");
    scanf("%d", kolumny);
    tab = (int**)malloc(wiersze * sizeof(int*)); // alokacja pamięci dla wierszy
    for (int i = 0; i < wiersze; i++)
    tab[i] = (int*)malloc(kolumny * sizeof(int)); // alokacja pamięci dla kolumn

    for (int i = 0; i < wiersze; i++)
    {    
        if (q->head == q->tail)
            return -1;

        q->tail++; // Inkrementujemy indeks tail
        // Jeśli był to ostatni element tablicy to ustawiamy wskaźnik na jej początek
        if (q->tail == BUF_SIZE)
            q->tail = 0;

        tab[i][q->tail] = q->buffer[q->tail];        // Odczytujemy wartość z bufora
        
    }
    return 0;    
}


int main()
{
    FILE *plik;
    char znak;
    plik = fopen("plik.txt", "r");
    if(plik==NULL)
    {
        printf("Plik ktorego szukasz nie istnieje");
        exit(0);
    }
    circ_buffer_t circBuff = { buffer, 0, 0 };
    char buffer[100];
    fgets(buffer, 100, plik);
    struct DaneZPliku record;
    while (fscanf(plik, "%u %f %f %f %f %f %f %f %f %f %f %f %f %f",
        &record.rok,
        &record.temp1,
        &record.temp2,
        &record.temp3,
        &record.temp4,
        &record.temp5,
        &record.temp6,
        &record.temp7,
        &record.temp8,
        &record.temp9,
        &record.temp10,
        &record.temp11,
        &record.temp12,
        &record.sredniaTeperatura) == 14) 
    {

    }
}

Nie wiem jak inkrementować indeksy tablicy w tej funkcji, aby program nie tracił danych.

komentarz 3 kwietnia 2020 przez j23 Mędrzec (194,920 p.)

Groch z kapustą.

extern float buffer[BUF_SIZE];
...

circ_buffer_t circBuff = { buffer, 0, 0 };

Na cholerę buffer jest typu float (i do tego extern) skoro circ_buffer_t::buffer jest typu DaneZPliku?

 

Po co w circ_buffer_get_char jakieś wywołania scanf i malloc, przecież rolą tej funkcji jest tylko odczyt struktury z bufora?

Tu masz poprawione funkcje:

int8_t circ_buffer_put_record(circ_buffer_t* q, struct DaneZPliku *record)
{
	uint8_t head_temp = q->head + 1;    
	 
	if (head_temp == BUF_SIZE) head_temp = 0;
 	if (head_temp == q->tail) return -1;
 
	q->buffer[head_temp] = *record;
	q->head = head_temp;            
	return 0;
}
 
struct DaneZPliku* circ_buffer_get_record(circ_buffer_t* q)
{
	if (q->head == q->tail) return NULL;
	q->tail++;
	if (q->tail == BUF_SIZE) q->tail = 0;
	return &q->buffer[q->tail];
}

Niech te funkcje robią tylko to, do czego zostały stworzone.

Nie wiem, o co chodzi z tymi tablicami. Skoro masz zapakować liczby z pliku do zwykłej tablicy, to po co ten bufor cykliczny? Jaka z niego tutaj korzyść?

 

 

komentarz 3 kwietnia 2020 przez kaminie318 Bywalec (2,070 p.)

Mam napisać program wczytujący dane z pliku do bufora cyklicznego wierszami a nastęnie kopiujący je do dynamicznej tablicy dwuwymiarowej. Problem w tym że już całkiem się w tym pogubiłem i mój kod to totalna głupota. Znalazłem na internecie implementacje z rodzajami zmienych jakich nigdy nie używałem(extern,uint_8t).Ponadto jest to mój pierwszy program w zwykłym c co dokłada jeszcze większej trudności.

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

#define BUF_SIZE 14

extern float buffer[BUF_SIZE];

struct DaneZPliku
{
	int rok;
	float temp1;
	float temp2;
	float temp3;
	float temp4;
	float temp5;
	float temp6;
	float temp7;
	float temp8;
	float temp9;
	float temp10;
	float temp11;
	float temp12;
	float sredniaTeperatura;
};

typedef struct {
	struct DaneZPliku * buffer;
	uint8_t head;
	uint8_t tail;
} circ_buffer_t;

int8_t circ_buffer_put_char(circ_buffer_t* q, struct DaneZPliku record)
{
	uint8_t head_temp = q->head + 1;	
	
	if (head_temp == BUF_SIZE)
		head_temp = 0;

	if (head_temp == q->tail)
		return -1;

	q->buffer[head_temp]=record;	// Jak wpisać moją strukturę do bufora ??? 
	q->head = head_temp;			

	return 0;
}

int8_t circ_buffer_get_char(circ_buffer_t* q)
{
	int wiersze, kolumny;
	int** tab;
	printf("Wiersze: ");
	scanf("%d", &wiersze);
	printf("Kolumny: ");
	scanf("%d", &kolumny);
	tab = (int**)malloc(wiersze * sizeof(int*)); // alokacja pamięci dla wierszy
	for (int i = 0; i < wiersze; i++)
	tab[i] = (int*)malloc(kolumny * sizeof(int)); // alokacja pamięci dla kolumn

	for (int i = 0; i < wiersze; i++)
	{	
		if (q->head == q->tail)
			return -1;

		q->tail++; // Inkrementujemy indeks tail
		// Jeśli był to ostatni element tablicy to ustawiamy wskaźnik na jej początek
		if (q->tail == BUF_SIZE)
			q->tail = 0;

		tab[i][q->tail] = &q->buffer[q->tail];		// Odczytujemy wartość z bufora
		
	}
	return 0;	
}


int main()
{
	FILE *plik;
	char znak;
	plik = fopen("plik.txt", "r");
	if(plik==NULL)
	{
		printf("Plik ktorego szukasz nie istnieje");
		exit(0);
	}
	circ_buffer_t circBuff = { buffer, 0, 0 };
	char buffer[100];
	fgets(buffer, 100, plik);
	struct DaneZPliku record;
	while (fscanf(plik, "%u %f %f %f %f %f %f %f %f %f %f %f %f %f",
		&record.rok,
		&record.temp1,
		&record.temp2,
		&record.temp3,
		&record.temp4,
		&record.temp5,
		&record.temp6,
		&record.temp7,
		&record.temp8,
		&record.temp9,
		&record.temp10,
		&record.temp11,
		&record.temp12,
		&record.sredniaTeperatura) == 14) 
	{
		circ_buffer_put_char(&circBuff, record);
		circ_buffer_get_char(&circBuff);
	}
}

Na tym poprzestałem i wiem że zapewne jest to głupota ale nie mam pojęcia jak to poprawić żeby działało.

komentarz 3 kwietnia 2020 przez j23 Mędrzec (194,920 p.)
Podałem Ci poprawione wersje funkcji.
komentarz 3 kwietnia 2020 przez kaminie318 Bywalec (2,070 p.)

Finalnie:

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

#define BUF_SIZE 14

extern float buffer[BUF_SIZE];

struct DaneZPliku
{
	int rok;
	float temp1;
	float temp2;
	float temp3;
	float temp4;
	float temp5;
	float temp6;
	float temp7;
	float temp8;
	float temp9;
	float temp10;
	float temp11;
	float temp12;
	float sredniaTeperatura;
};

typedef struct {
	struct DaneZPliku * buffer;
	uint8_t head;
	uint8_t tail;
} circ_buffer_t;

int8_t circ_buffer_put_record(circ_buffer_t* q, struct DaneZPliku* record)
{
	uint8_t head_temp = q->head + 1;

	if (head_temp == BUF_SIZE) head_temp = 0;
	if (head_temp == q->tail) return -1;

	q->buffer[head_temp] = *record;
	q->head = head_temp;
	return 0;
}


struct DaneZPliku* circ_buffer_get_record(circ_buffer_t* q)
{
	if (q->head == q->tail) return NULL;
	q->tail++;
	if (q->tail == BUF_SIZE) q->tail = 0;
	return &q->buffer[q->tail];
}

int main()
{
	FILE *plik;
	plik = fopen("plik.txt", "r");
	if(plik==NULL)
	{
		printf("Plik ktorego szukasz nie istnieje");
		exit(0);
	}
	struct DaneZPliku record;
	circ_buffer_t circBuff = {&record, 0, 0 };
	char buffer[100];
	fgets(buffer, 100, plik);
	while (fscanf(plik, "%u %f %f %f %f %f %f %f %f %f %f %f %f %f",
		&record.rok,
		&record.temp1,
		&record.temp2,
		&record.temp3,
		&record.temp4,
		&record.temp5,
		&record.temp6,
		&record.temp7,
		&record.temp8,
		&record.temp9,
		&record.temp10,
		&record.temp11,
		&record.temp12,
		&record.sredniaTeperatura) == 14) 
	{
		circ_buffer_put_record(&circBuff, &record);
		circ_buffer_get_record(&circBuff);
	}
}

Odpalać się odpala, jednak wyskakuje błąd"naruszenie zasad dostępu podczas zapisu" podczas while'a średniaTemperatura(Tak przynajmniej vs mi podkresla). Nie mam siły już

komentarz 3 kwietnia 2020 przez j23 Mędrzec (194,920 p.)

Nie przeczytałeś mojego przedostatniego posta. Jeszcze raz:

Na cholerę buffer jest typu float (i do tego extern) skoro circ_buffer_t::buffer jest typu DaneZPliku?

komentarz 3 kwietnia 2020 przez kaminie318 Bywalec (2,070 p.)
Przerobiłem,nadal ten sam błąd.
komentarz 4 kwietnia 2020 przez j23 Mędrzec (194,920 p.)
Pokaż poprawiony kod.
komentarz 4 kwietnia 2020 przez kaminie318 Bywalec (2,070 p.)
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>

#define BUF_SIZE 14

struct DaneZPliku *buffer[BUF_SIZE];

struct DaneZPliku
{
	int rok;
	float temp1;
	float temp2;
	float temp3;
	float temp4;
	float temp5;
	float temp6;
	float temp7;
	float temp8;
	float temp9;
	float temp10;
	float temp11;
	float temp12;
	float sredniaTeperatura;
};

typedef struct {
	struct DaneZPliku * buffer;
	uint8_t head;
	uint8_t tail;
} circ_buffer_t;

int8_t circ_buffer_put_record(circ_buffer_t* q, struct DaneZPliku* record)
{
	uint8_t head_temp = q->head + 1;

	if (head_temp == BUF_SIZE) head_temp = 0;
	if (head_temp == q->tail) return -1;

	q->buffer[head_temp] = *record;
	q->head = head_temp;
	return 0;
}


struct DaneZPliku* circ_buffer_get_record(circ_buffer_t* q)
{
	if (q->head == q->tail) return NULL;
	q->tail++;
	if (q->tail == BUF_SIZE) q->tail = 0;
	return &q->buffer[q->tail];
}

int main()
{
	FILE *plik;
	plik = fopen("plik.txt", "r");
	if(plik==NULL)
	{
		printf("Plik ktorego szukasz nie istnieje");
		exit(0);
	}
	char buffer[100];
	fgets(buffer, 100, plik);
	struct DaneZPliku record;
	circ_buffer_t circBuff = {&record, 0, 0 };
	while (fscanf(plik, "%u %f %f %f %f %f %f %f %f %f %f %f %f %f",
		&record.rok,
		&record.temp1,
		&record.temp2,
		&record.temp3,
		&record.temp4,
		&record.temp5,
		&record.temp6,
		&record.temp7,
		&record.temp8,
		&record.temp9,
		&record.temp10,
		&record.temp11,
		&record.temp12,
		&record.sredniaTeperatura) == 14) 
	{
		circ_buffer_put_record(&circBuff, &record);
		circ_buffer_get_record(&circBuff);
	}
}

 

komentarz 4 kwietnia 2020 przez j23 Mędrzec (194,920 p.)

Nie:

struct DaneZPliku *buffer[BUF_SIZE];

tylko struct DaneZPliku buffer[BUF_SIZE];

 

PS. tu wychodzi przewaga C++ nad C, jego ściślejsza kontrola typów. Przy takim błędzie kod najzwyczajniej nie skompilowałby się.

komentarz 4 kwietnia 2020 przez kaminie318 Bywalec (2,070 p.)
Przerobiłem, cały czas naruszanie zasad dostępu podczas zapisywania w tej samej linijce.
komentarz 5 kwietnia 2020 przez j23 Mędrzec (194,920 p.)
#define BUF_SIZE 14
 
typedef struct 
{
    int rok;
    float temp1;
    float temp2;
    float temp3;
    float temp4;
    float temp5;
    float temp6;
    float temp7;
    float temp8;
    float temp9;
    float temp10;
    float temp11;
    float temp12;
    float sredniaTeperatura;
} record_t;

typedef struct {
    record_t * buffer;
    uint8_t head;
    uint8_t tail;
} circ_buffer_t;

 
int8_t circ_buffer_put_record(circ_buffer_t* q, record_t* record)
{
    uint8_t head_temp = q->head + 1;
 
    if (head_temp == BUF_SIZE) head_temp = 0;
    if (head_temp == q->tail) return -1;
 
    q->buffer[head_temp] = *record;
    q->head = head_temp;
    return 0;
}
 
 
record_t* circ_buffer_get_record(circ_buffer_t* q)
{
    if (q->head == q->tail) return NULL;
    ++q->tail;
    if (q->tail == BUF_SIZE) q->tail = 0;
    return q->buffer + q->tail;
}
 
int main()
{
    record_t buffer[BUF_SIZE];
    circ_buffer_t circBuff = { buffer, 0, 0 };
    record_t record;

    FILE *plik = fopen("data.txt", "r");
    if(plik == NULL) {
        printf("Plik ktorego szukasz nie istnieje");
        exit(0);
    }
    
    char line[100];
    fgets(line, 100, plik);
    
    while (fscanf(plik, "%u %f %f %f %f %f %f %f %f %f %f %f %f %f",
		    &record.rok,
		    &record.temp1,
		    &record.temp2,
		    &record.temp3,
		    &record.temp4,
		    &record.temp5,
		    &record.temp6,
		    &record.temp7,
		    &record.temp8,
		    &record.temp9,
		    &record.temp10,
		    &record.temp11,
		    &record.temp12,
		    &record.sredniaTeperatura) == 14) 
    {
        if(circ_buffer_put_record(&circBuff, &record) == -1) {
        	printf("The buffer is full\n");
        	break;
        }
    }
    

}

Dlaczego polu circ_buffer_t::buffer przypisałeś adres zmiennej record, zamiast dać tam tablicę buffer? Zwracaj uwagę na to, co robisz.

Nie zauważyłem tego wcześniej, ale najpierw definiujesz tablicę (buffer) dla typu (DaneZPliku), który definiowany jest linię niżej. Powinno być odwrotnie.

komentarz 5 kwietnia 2020 przez kaminie318 Bywalec (2,070 p.)
Dzięki, chyba filtruje w końcu ten plik.Zwiększyłem rozmiar bufora do 39(ponieważ daty są od 1980 do 2019) tylko ku mojemu zaskoczeniu program kończy się na 2017 roku a nie 2019.Co może być przyczyną? Czy wpisując dane do dwuwymarowej tablicy dynamicznej bawić się w nowe funkcje odpowiedzialne za to czy od razu w mainie zrobić taką tablice i wpisywać do niej te dane z bufora?
komentarz 5 kwietnia 2020 przez j23 Mędrzec (194,920 p.)

Podział kodu na funkcje jest zawsze pożądany - zwiększa to jego czytelność.

Co może być przyczyną?

Jeśli mowa o kodzie, który podałem, to on kończy czytanie, gdy bufor jest pełny. Być może dlatego nie czyta Ci wszystkiego.

Szczerze mówiąc nie wiem, po co tutaj ten bufor cykliczny, bo żadna z niego korzyść w tym konkretnym przypadku. On ma zastosowanie w przypadku asynchronicznej relacji producent -> konsument.

komentarz 5 kwietnia 2020 przez kaminie318 Bywalec (2,070 p.)

Po prostu dostaliśmy takie zadanie na studiach, dane z bufora cyklicznego mają zostać wpisane do tablicy dynamicznej dwuwymiarowej i jest do niego jeszcze kilka podpunktów. Zrobiłem to bez osobnej funkcji jednak. W jakim formacie wyświetlać linijki w tablicy bo zakładam że raczej nie %d. Co tutaj jest nie tak ? 

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

#define BUF_SIZE 40
  
typedef struct
{
    int rok;
    float temp1;
    float temp2;
    float temp3;
    float temp4;
    float temp5;
    float temp6;
    float temp7;
    float temp8;
    float temp9;
    float temp10;
    float temp11;
    float temp12;
    float sredniaTeperatura;
} record_t;
 
typedef struct {
    record_t * buffer;
    uint8_t head;
    uint8_t tail;
} circ_buffer_t;
 
  
int8_t circ_buffer_put_record(circ_buffer_t* q, record_t* record)
{
    uint8_t head_temp = q->head + 1;
  
    if (head_temp == BUF_SIZE) head_temp = 0;
    if (head_temp == q->tail) return -1;
  
    q->buffer[head_temp] = *record;
    q->head = head_temp;
    return 0;
}
  
  
record_t* circ_buffer_get_record(circ_buffer_t* q)
{
    if (q->head == q->tail) return NULL;
    ++q->tail;
    if (q->tail == BUF_SIZE) q->tail = 0;
    return q->buffer + q->tail;
}
  
int main()
{
    record_t buffer[BUF_SIZE];
    circ_buffer_t circBuff = { buffer, 0, 0 };
    record_t record;
 
    FILE *plik = fopen("plik.txt", "r");
    if(plik == NULL) {
        printf("Plik ktorego szukasz nie istnieje");
        exit(0);
    }
     
    int wier =40, col=14;
    int** tab;
    int i = 0;

    tab = (int**)malloc(wier * sizeof(int*)); 
    for (int i = 0; i < wier; i++)
        tab[i] = (int*)malloc(col * sizeof(int)); 

    char line[100];
    fgets(line, 100, plik);
     
    while (fscanf(plik, "%u %f %f %f %f %f %f %f %f %f %f %f %f %f",
            &record.rok,
            &record.temp1,
            &record.temp2,
            &record.temp3,
            &record.temp4,
            &record.temp5,
            &record.temp6,
            &record.temp7,
            &record.temp8,
            &record.temp9,
            &record.temp10,
            &record.temp11,
            &record.temp12,
            &record.sredniaTeperatura) == 14) 
    {
        if(circ_buffer_put_record(&circBuff, &record) == -1) 
        {
            printf("The buffer is full\n");
            break;
        }
         tab[i][col] == &circBuff;
         i++;
    }

    for (int i = 0; i < wier; i++) {
        for (int j = 0; j < col; j++) {
            printf("%d", tab[i][j]);
        }
        printf("\n");
    }
 
}

 

komentarz 5 kwietnia 2020 przez j23 Mędrzec (194,920 p.)

Co tutaj jest nie tak ? 

To:

tab[i][col] == &circBuff;

Co Ty tu próbujesz robić?

int** tab;

Dane w pliku to w większości liczby typu float. Dlaczego tablica jest typu int?

 

Po prostu dostaliśmy takie zadanie na studiach

Domyśliłem się, tylko jaki w tym sens dydaktyczny.

komentarz 6 kwietnia 2020 przez kaminie318 Bywalec (2,070 p.)
Zgadza się, tablica intów mój błąd. Nie wiem jak przekazać te dane do tablicy, po jakich elementach inkrementować i co robić .Sensu dydaktycznego zapewnie nie ma, ale prowadzący przedmiot wymyślił takie i męczę się z tym już 4 dzień z mizernymi efektami.
komentarz 6 kwietnia 2020 przez j23 Mędrzec (194,920 p.)

Nie wiem jak przekazać te dane do tablicy 

Funkcją circ_buffer_get_record ściągasz rekord z bufora i zapisujesz pola struktury do kolejnych kolumn wiersza tablicy 2D. Robisz to tak długo (w pętli), aż circ_buffer_get_record zwróci NULL lub skończy się tablica.

komentarz 7 kwietnia 2020 przez kaminie318 Bywalec (2,070 p.)

Mam coś takiego. Próbuje dostać się do danych z bufora, ale bez progresu.Bardzo gubię się pomiędzy odwołaniami do bufora a zwykłej struktury.

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

#define BUF_SIZE 40

typedef struct
{
    int rok;
    float temp1;
    float temp2;
    float temp3;
    float temp4;
    float temp5;
    float temp6;
    float temp7;
    float temp8;
    float temp9;
    float temp10;
    float temp11;
    float temp12;
    float sredniaTeperatura;
} record_t;


typedef struct {
    record_t* buffer;
    uint8_t head;
    uint8_t tail;
} circ_buffer_t;


int8_t circ_buffer_put_record(circ_buffer_t* q, record_t* record)
{
    uint8_t head_temp = q->head + 1;

    if (head_temp == BUF_SIZE) head_temp = 0;
    if (head_temp == q->tail) return -1;

    q->buffer[head_temp] = *record;
    q->head = head_temp;
    return 0;
}


record_t* circ_buffer_get_record(circ_buffer_t* q)
{
    int col = 14;
    int wier = BUF_SIZE;
    float** tab;

    tab = (int**)malloc(wier * sizeof(int*));
    for (int i = 0; i < wier; i++)
        tab[i] = (float*)malloc(col * sizeof(float));
    for (int i = 0; circ_buffer_get_record != NULL; i++)
    {
        for (int j = 0; j < col; j++)
        {
            tab[i][j] == q->buffer[j];
        }
    }
    if (q->head == q->tail) return NULL;
    ++q->tail;
    if (q->tail == BUF_SIZE) q->tail = 0;
    return q->buffer + q->tail;
}

int main()
{
    record_t buffer[BUF_SIZE];
    circ_buffer_t circBuff = { buffer, 0, 0 };
    record_t record;

    FILE* plik = fopen("plik.txt", "r");
    if (plik == NULL) {
        printf("Plik ktorego szukasz nie istnieje");
        exit(0);
    }

    char line[100];
    fgets(line, 100, plik);

    while (fscanf(plik, "%u %f %f %f %f %f %f %f %f %f %f %f %f %f",
        &record.rok,
        &record.temp1,
        &record.temp2,
        &record.temp3,
        &record.temp4,
        &record.temp5,
        &record.temp6,
        &record.temp7,
        &record.temp8,
        &record.temp9,
        &record.temp10,
        &record.temp11,
        &record.temp12,
        &record.sredniaTeperatura) == 14)
    {
        if (circ_buffer_put_record(&circBuff, &record) == -1) {
            printf("The buffer is full\n");
            break;
        }
        circ_buffer_get_record(&circBuff);
    }

}

 

komentarz 7 kwietnia 2020 przez j23 Mędrzec (194,920 p.)

Po co w ogóle ruszasz circ_buffer_get_record? Ta funkcja jest kompletna! Jej rolą jest ściągnąć z bufora jeden rekord i nic więcej. Jak chcesz poprać następny rekord, to wywołujesz ją jeszcze raz. I tak w kółko, aż zwróci wartość NULL.

record_t* rec;

while (rec = circ_buffer_get_record(&circBuff)) {
    /* 
        tu dodajesz kolejne pola rec do tablicy 
    */
}

Jeszcze raz zadam pytanie:

tab[i][j] == q->buffer[j];

Możesz wytłumaczyć, co właściwie tu robisz? Możesz powiedzieć jakiego typu jest lewa i prawa strona tego... ekhem... "przypisania"?

komentarz 7 kwietnia 2020 przez kaminie318 Bywalec (2,070 p.)
Skoro tablica do jednego wymiaru bierze dane z bufora(czyli de facto cały rekord), to czy musi być ona dwuwymiarowa? czy nie wystarczy tablica 1D na poszczególne wiersze ? Dodatkowo jeżeli w tej pęlit while chce wyświetlić dane z bufora(jeden wiersz) to jakiego formatu muszę użyć w printf?
komentarz 7 kwietnia 2020 przez j23 Mędrzec (194,920 p.)

Dokładnie takiego samego jak dla fscanf, tylko nie podajesz adresów pól a wartości.

czy musi być ona dwuwymiarowa?

Nie znam treści zadania, więc nie wiem. Normalnie wystarczyłaby zwykła tablica struktur record_t.

komentarz 8 kwietnia 2020 przez j23 Mędrzec (194,920 p.)

Odnośnie tego -> link

  • linia 14: pominę kwestię użycia złego operatora. Próbujesz przypisać elementowi tablicy, który jest typu float, wartość wskaźnika rec. I dokładnie tę samą wartość przypisujesz wszystkim elementom tablicy w wierszu. rec wskazuje na strukturę typu record_t, która posiada 14 pól, i tak się składa, że wiersz tablicy też ma 14 elementów. Połącz fakty.
  • linia 12: format-string jest ok, tylko zrobiłeś błąd jak w linii 14. format-string mówi o 14 parametrach i tyle funkcja printf powinna dostać. Ile masz elementów w wierszu tablicy? Połącz fakty.

Tu masz krótko o strukturach -> link

komentarz 9 kwietnia 2020 przez kaminie318 Bywalec (2,070 p.)
Dostałem wskazówkę odnośnie tego zadania. Rozmiar bufora miałem przyjąć na dwa wiersze a potem rozmiar bufora miał rosnąć z danymi(korzystac z malloc i realloc), potem należało przeliczyć dane. Nie za bardzo wiem jak to interpretować i wykorzystać w tym zadaniu.
komentarz 9 kwietnia 2020 przez j23 Mędrzec (194,920 p.)
O jakim buforze piszesz? Tym cyklicznym?
komentarz 9 kwietnia 2020 przez kaminie318 Bywalec (2,070 p.)
Tak, nie wiem jak zwiększać jego dane w trakcie programu. Żeby rozmiar bufora nie był statyczny, tylko zwiększał się wraz z liczbą wierszy. Chciałem wrzucić alokację do tej pierwszej funkcji put_record, ale nie wiem jak zmienić warunek head_temp==BUFF_SIZE wraz z wzrastającą liczbą zaalokowanej pamięci, aby kiedyś się ta funkcja skończyła i head_temp był równy zero.
komentarz 9 kwietnia 2020 przez j23 Mędrzec (194,920 p.)
Nic nie wrzucaj to tych funkcji, bo jak już pisałem, te funkcje są kompletne i robią to, do czego zostały stworzone. Jak chcesz wstawić tę relokację pamięci do funkcji, to zrób po prostu nową, która będzie tylko do tego zadania.
komentarz 10 kwietnia 2020 przez kaminie318 Bywalec (2,070 p.)

Okej, ale nadal nie rozumiem jak mam skorzystać z realloca do zwiększania bufora. Najpierw ustawiam rozmiar bufora na 3 wiersze a potem systematycznie zwiększam o 5. Jak to upchać ? 

int main()
{
    int poczRozmiarBufora=3;
    int* rozmiarBufora;
    void* temp;
    rozmiarBufora = malloc(poczRozmiarBufora * sizeof(int));
    int rozmiarBuforaWIntach = rozmiarBufora / sizeof(int);

    temp = realloc(rozmiarBufora, (poczRozmiarBufora+5) * sizeof(int));

    record_t buffer[rozmiarBufora];
    circ_buffer_t circBuff = { buffer, 0, 0 };
    record_t record;

   int col = 14;
   int wier = BUF_SIZE;
   float** tab;

   tab = (int**)malloc(wier * sizeof(int*));
   for (int i = 0; i < wier; i++)
       tab[i] = (float*)malloc(col * sizeof(float));


    FILE* plik = fopen("plik.txt", "r");
    if (plik == NULL) {
        printf("Plik ktorego szukasz nie istnieje");
        exit(0);
    }

    char line[100];
    fgets(line, 100, plik);

    while (fscanf(plik, "%u %f %f %f %f %f %f %f %f %f %f %f %f %f",
        &record.rok,
        &record.temp1,
        &record.temp2,
        &record.temp3,
        &record.temp4,
        &record.temp5,
        &record.temp6,
        &record.temp7,
        &record.temp8,
        &record.temp9,
        &record.temp10,
        &record.temp11,
        &record.temp12,
        &record.sredniaTeperatura) == 14)
    {
        if (circ_buffer_put_record(&circBuff, &record) == -1) {
            printf("Bufor jest pelny!\n");
            break;
        }
    }

    //int i = 0;
    //record_t* rec;
    //while (rec = circ_buffer_get_record(&circBuff)) 
    //{
    //    for (int j = 0; j < 14; j++)
    //    {
    //        tab[i][j] == rec;
    //    }
    //    i++;
    //}

    ////wyswietlanie 
    //for (int i = 0; i < BUF_SIZE; i++)
    //{
    //    for (int j = 0; j < 14; j++)
    //    {
    //        printf("%u %f %f %f %f %f %f %f %f %f %f %f %f %f", tab[i][j]);
    //    }
    //}
}

 

komentarz 10 kwietnia 2020 przez j23 Mędrzec (194,920 p.)
edycja 13 kwietnia 2020 przez j23

Można tak:

typedef struct {
    float** ptr;
    size_t size;
    size_t capacity;
} array_t;

void array_init(array_t* array)
{
    array->size = 0;
    array->capacity = 2;
    array->ptr = malloc(sizeof(float*) * array->capacity);

    for (int i = 0; i < array->capacity; ++i)
        array->ptr[i] = malloc(sizeof(float) * 14);
}

void array_append_record(array_t* array, record_t* rec)
{
    if (array->size == array->capacity) {
        size_t new_cap = 175 * array->capacity / 100;
        array->ptr = realloc(array->ptr, sizeof(float*) * new_cap);

        for (int i = array->capacity; i < new_cap; ++i)
            array->ptr[i] = malloc(sizeof(float) * 14);

        array->capacity = new_cap;
    }

    float* row = array->ptr[array->size++];
    row[0] = rec->rok;
    row[1] = rec->temp1;
    row[2] = rec->temp2;
    row[3] = rec->temp3;

    // itd.
}

// definiowanie tablicy
array_t array;

array_init(&array);

// w pętli
array_append_record(&array, &rec);

 

PS. mogą być jakieś błędy. Pisałem z palca, bez testów, na szybko.

komentarz 10 kwietnia 2020 przez kaminie318 Bywalec (2,070 p.)

Ale na co ja mam teraz pozamieniać BUF_SIZE ?Czemu ta funkcja array_append_record mnoży razy 175? Dla mnie to już czarna magia co się dzieje w tym programie.

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

#define BUF_SIZE 3

typedef struct
{
    int rok;
    float temp1;
    float temp2;
    float temp3;
    float temp4;
    float temp5;
    float temp6;
    float temp7;
    float temp8;
    float temp9;
    float temp10;
    float temp11;
    float temp12;
    float sredniaTeperatura;
} record_t;


typedef struct {
    record_t* buffer;
    uint8_t head;
    uint8_t tail;
} circ_buffer_t;


int8_t circ_buffer_put_record(circ_buffer_t* q, record_t* record)
{
    uint8_t head_temp = q->head + 1;

    if (head_temp == BUF_SIZE) 
        head_temp = 0;

    if (head_temp == q->tail)
        return -1;

    q->buffer[head_temp] = *record;
    q->head = head_temp;
    return 0;
}


record_t* circ_buffer_get_record(circ_buffer_t* q)
{
    if (q->head == q->tail) return NULL;
    ++q->tail;
    if (q->tail == BUF_SIZE) q->tail = 0;
    return q->buffer + q->tail;
}

typedef struct {
    float** ptr;
    size_t size;
    size_t capacity;
} array_t;

void array_init(array_t* array)
{
    array->capacity = 2;
    array->ptr = malloc(sizeof(float*) * array->capacity);

    for (int i = 0; i < array->capacity; ++i)
        array->ptr[i] = malloc(sizeof(float) * 14);
}

void array_append_record(array_t* array, record_t* rec)
{
    if (array->size + 1 == array->capacity) 
    {

        size_t new_cap = 175 * array->capacity / 100;
        array->ptr = realloc(array->ptr, sizeof(float*) * new_cap);

        for (int i = array->capacity; i < new_cap; ++i)
            array->ptr[i] = malloc(sizeof(float) * 14);

        array->capacity = new_cap;
    }

    float* row = array->ptr[array->size++];
    row[0] = rec->rok;
    row[1] = rec->temp1;
    row[2] = rec->temp2;
    row[3] = rec->temp3;
    row[4] = rec->temp4;
    row[5] = rec->temp5;
    row[6] = rec->temp6;
    row[7] = rec->temp7;
    row[8] = rec->temp8;
    row[9] = rec->temp9;
    row[10] = rec->temp10;
    row[11] = rec->temp11;
    row[12] = rec->temp12;
    row[13] = rec->sredniaTeperatura;
    // itd.
}

int main()
{
    array_t array;

    record_t* rec;

    array_init(&array);
    
    array_append_record(&array, &rec);

    record_t buffer[???];
    circ_buffer_t circBuff = { buffer, 0, 0 };
    record_t record;

   int col = 14;
   int wier = BUF_SIZE;
   float** tab;

   tab = (int**)malloc(wier * sizeof(int*));
   for (int i = 0; i < wier; i++)
       tab[i] = (float*)malloc(col * sizeof(float));


    FILE* plik = fopen("plik.txt", "r");
    if (plik == NULL) {
        printf("Plik ktorego szukasz nie istnieje");
        exit(0);
    }

    char line[100];
    fgets(line, 100, plik);

    while (fscanf(plik, "%u %f %f %f %f %f %f %f %f %f %f %f %f %f",
        &record.rok,
        &record.temp1,
        &record.temp2,
        &record.temp3,
        &record.temp4,
        &record.temp5,
        &record.temp6,
        &record.temp7,
        &record.temp8,
        &record.temp9,
        &record.temp10,
        &record.temp11,
        &record.temp12,
        &record.sredniaTeperatura) == 14)
    {
        if (circ_buffer_put_record(&circBuff, &record) == -1) {
            printf("Bufor jest pelny!\n");
            break;
        }
    }

    //int i = 0;
    //record_t* rec;
    //while (rec = circ_buffer_get_record(&circBuff)) 
    //{
    //    for (int j = 0; j < 14; j++)
    //    {
    //        tab[i][j] == rec;
    //    }
    //    i++;
    //}

    ////wyswietlanie 
    //for (int i = 0; i < BUF_SIZE; i++)
    //{
    //    for (int j = 0; j < 14; j++)
    //    {
    //        printf("%u %f %f %f %f %f %f %f %f %f %f %f %f %f", tab[i][j]);
    //    }
    //}
}

 

komentarz 10 kwietnia 2020 przez j23 Mędrzec (194,920 p.)

Ale na co ja mam teraz pozamieniać BUF_SIZE ?

A po co w ogóle zmieniać? Temat bufora cyklicznego jest już zamknięty. Teraz zajmujemy się dynamiczną tablicą.

Czemu ta funkcja array_append_record mnoży razy 175?

Każda realokacja jest o 75% większa od aktualnego rozmiaru tablicy (capacity). Ot, zwykły rachunek procentowy na typie całkowitoliczbowym.

Dla mnie to już czarna magia co się dzieje w tym programie.

Trzeba analizować kod, które tutaj dostajesz, i starać się go zrozumieć.

   int col = 14;
   int wier = BUF_SIZE;
   float** tab;
 
   tab = (int**)malloc(wier * sizeof(int*));
   for (int i = 0; i < wier; i++)
       tab[i] = (float*)malloc(col * sizeof(float));

Wywal to. Teraz tablica jest realizowana przez array_t, array_initarray_append_record.

komentarz 10 kwietnia 2020 przez kaminie318 Bywalec (2,070 p.)
Właśnie o to chodzi ,że rozmiar bufora ma rosnać wraz z otrzymanymi danymi(realloc), więc nie wiem czy mogę przyjąć makrodefinicje BUF_SIZE na 40 wierszy, czyli de facto wszystkie wiersze z pliku.
komentarz 10 kwietnia 2020 przez j23 Mędrzec (194,920 p.)

Przecież BUF_SIZE odnosi się do bufora cyklicznego! array_append_record jest odpowiedzialna za poszerzanie tablicy array_t w miarę dodawania nowych rekordów.

Według tego, co piszesz, twoim zadaniem jest zrobienie czegoś takiego :

plik → bufor cykliczny (circ_buffer_t) → tablica dynamiczna (array_t) → standardowe wyjście (printf).

Wszystkie elementy już masz zaimplementowane, połącz je i nie wydziwiaj.

 

komentarz 10 kwietnia 2020 przez kaminie318 Bywalec (2,070 p.)
Dokładnie taki jest cel jak napisałeś.Jednak rozmiar bufora cyklicznego(BUFF_SIZE) musi rosnąć wraz z danymi (zaczyna od 3 konczy na 40 bo tyle jest wierszy). A ilość miejsc w  tablicy dynamicznej do której muszą być wpisywane dane na początku ma wynosić 10, a potem rosnąć o stały krok(5 miejsc) jeżeli brakuje miejsca na dane.Trochę to zawiłe i sam się z tym gubię, ale prowadzący chyba lubi mieszać w głowie.
komentarz 11 kwietnia 2020 przez j23 Mędrzec (194,920 p.)

Jednak rozmiar bufora cyklicznego(BUFF_SIZE) musi rosnąć wraz z danymi

Nonsens. Przecież jedną z cech bufora cyklicznego jest to, że ma stały rozmiar! Dlatego jest cykliczny, bo gdyby zwiększał się sukcesywnie wraz ze wstawianymi danymi, to ta jego cykliczność byłaby pozbawiona sensu, niepotrzebna. Zresztą wcześniej pisałem, że użycie tego typu bufora w tym przypadku jest pozbawione sensu, bo niczego on nie rozwiązuje, a jedynie niepotrzebnie komplikuje zadanie.

ale prowadzący chyba lubi mieszać w głowie

Albo prowadzący nie wie, czego chce, albo Ty coś tutaj źle przedstawiasz.

 

komentarz 11 kwietnia 2020 przez kaminie318 Bywalec (2,070 p.)

Komentarz do zadania. Może po prostu ja coś źle rozumiem:

"To malo, jak na dzialanie programu - rozmiar bufora mial rosnac z danymi (realloc), potem nalezalo przeliczyc dane". Kod który wysłałem:

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

#define BUF_SIZE 40

typedef struct
{
    int rok;
    float temp1;
    float temp2;
    float temp3;
    float temp4;
    float temp5;
    float temp6;
    float temp7;
    float temp8;
    float temp9;
    float temp10;
    float temp11;
    float temp12;
    float sredniaTeperatura;
} record_t;


typedef struct {
    record_t* buffer;
    uint8_t head;
    uint8_t tail;
} circ_buffer_t;


int8_t circ_buffer_put_record(circ_buffer_t* q, record_t* record)
{
    uint8_t head_temp = q->head + 1;

    if (head_temp == BUF_SIZE) head_temp = 0;
    if (head_temp == q->tail) return -1;

    q->buffer[head_temp] = *record;
    q->head = head_temp;
    return 0;
}


record_t* circ_buffer_get_record(circ_buffer_t* q)
{
    if (q->head == q->tail) return NULL;
    ++q->tail;
    if (q->tail == BUF_SIZE) q->tail = 0;
    return q->buffer + q->tail;
}

int main()
{
    record_t buffer[BUF_SIZE];
    circ_buffer_t circBuff = { buffer, 0, 0 };
    record_t record;

    FILE* plik = fopen("plik.txt", "r");
    if (plik == NULL) {
        printf("Plik ktorego szukasz nie istnieje");
        exit(0);
    }

    char line[100];
    fgets(line, 100, plik);

    while (fscanf(plik, "%u %f %f %f %f %f %f %f %f %f %f %f %f %f",
        &record.rok,
        &record.temp1,
        &record.temp2,
        &record.temp3,
        &record.temp4,
        &record.temp5,
        &record.temp6,
        &record.temp7,
        &record.temp8,
        &record.temp9,
        &record.temp10,
        &record.temp11,
        &record.temp12,
        &record.sredniaTeperatura) == 14)
    {
        if (circ_buffer_put_record(&circBuff, &record) == -1) {
            printf("The buffer is full\n");
            break;
        }
    }

}

Jak jest to niemożliwe to będę robił na stałym rozmiarze bufora. Wysłałbym polecenie do zadania, ale nie wiem czy mogę to zrobić zgodnie z regulaminem forum.

komentarz 11 kwietnia 2020 przez j23 Mędrzec (194,920 p.)
Wyślij na priva.
komentarz 12 kwietnia 2020 przez j23 Mędrzec (194,920 p.)
edycja 13 kwietnia 2020 przez j23

No i wszystko jasne.  Pomimo, że dalej nie rozumiem sensu użycia bufora cyklicznego, to BUF_SIZE ustaw na 3, i nic więcej nie musisz z nim robić. Co do tablicy, możesz zmienić nieco obie funkcje:

void array_init(array_t* array)
{
    array->size = 0;
    array->capacity = 10;
    array->ptr = malloc(sizeof(float*) * array->capacity);

    for (int i = 0; i < array->capacity; ++i)
        array->ptr[i] = malloc(sizeof(float) * 14);
}

void array_append_record(array_t* array, record_t* rec)
{
    if (array->size == array->capacity) {

        size_t new_cap = array->capacity + 5;
        array->ptr = realloc(array->ptr, sizeof(float*) * new_cap);

        for (int i = array->capacity; i < new_cap; ++i)
            array->ptr[i] = malloc(sizeof(float) * 14);

        array->capacity = new_cap;
    }

    float* row = array->ptr[array->size++];
    row[0] = rec->rok;
    row[1] = rec->temp1;
    row[2] = rec->temp2;
    row[3] = rec->temp3;

    // itd.
}

Tak, by na start prealokowane było 10 wierszy, a później o pięć więcej (tak jak jest w zadaniu). W sumie jakbyś zostawił te 75% procent, też by było dobrze.

 

Jeśli chodzi o przenoszenie danych z bufora cyklicznego do tablicy, to można tak:

/* w głównej pętli czytającej z pliku */

record_t* rec;

if (circ_buffer_put_record(&circBuff, &record) == -1) {
    while (rec = circ_buffer_get_record(&circBuff)) {
        array_append_record(&array, rec);
    }
}

Z resztą podpunktów powinieneś dać sobie radę.

komentarz 12 kwietnia 2020 przez kaminie318 Bywalec (2,070 p.)

Problem z zapisem do tablicy(zaznaczyłem w kodzie). Próbowałem przerabiać, ale nici z tego:

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

#define BUF_SIZE 3

typedef struct
{
    int rok;
    float temp1;
    float temp2;
    float temp3;
    float temp4;
    float temp5;
    float temp6;
    float temp7;
    float temp8;
    float temp9;
    float temp10;
    float temp11;
    float temp12;
    float sredniaTeperatura;
} record_t;


typedef struct {
    record_t* buffer;
    uint8_t head;
    uint8_t tail;
} circ_buffer_t;


int8_t circ_buffer_put_record(circ_buffer_t* q, record_t* record)
{
    uint8_t head_temp = q->head + 1;

    if (head_temp == BUF_SIZE) 
        head_temp = 0;

    if (head_temp == q->tail)
        return -1;

    q->buffer[head_temp] = *record;
    q->head = head_temp;
    return 0;
}


record_t* circ_buffer_get_record(circ_buffer_t* q)
{
    if (q->head == q->tail) return NULL;
    ++q->tail;
    if (q->tail == BUF_SIZE) q->tail = 0;
    return q->buffer + q->tail;
}

typedef struct {
    float** ptr;
    size_t size;
    size_t capacity;
} array_t;


void array_init(array_t* array)
{
    array->capacity = 10;
    array->ptr = malloc(sizeof(float*) * array->capacity);

    for (int i = 0; i < array->capacity; ++i)
        array->ptr[i] = malloc(sizeof(float) * 14);
}


void array_append_record(array_t* array, record_t* rec)
{
    if (array->size + 1 == array->capacity) {

        size_t new_cap = array->capacity + 5;
        array->ptr = realloc(array->ptr, sizeof(float*) * new_cap);

        for (int i = array->capacity; i < new_cap; ++i)
            array->ptr[i] = malloc(sizeof(float) * 14);

        array->capacity = new_cap;
    }

    float* row = array->ptr[array->size++];     //TUTAJ PROBLEM,NARUSZENIE DOSTEPU DO ODCZYTU
    row[0] = rec->rok;
    row[1] = rec->temp1;
    row[2] = rec->temp2;
    row[3] = rec->temp3;
    row[4] = rec->temp4;
    row[5] = rec->temp5;
    row[6] = rec->temp6;
    row[7] = rec->temp7;
    row[8] = rec->temp8;
    row[9] = rec->temp9;
    row[10] = rec->temp10;
    row[11] = rec->temp11;
    row[12] = rec->temp12;
    row[13] = rec->sredniaTeperatura;
}

int main()
{
    // definiowanie tablicy
    array_t array;

    //array_init(&array);

    record_t buffer[BUF_SIZE];
    circ_buffer_t circBuff = { buffer, 0, 0 };
    record_t record;

    FILE* plik = fopen("plik.txt", "r");
    if (plik == NULL) {
        printf("Plik ktorego szukasz nie istnieje");
        exit(0);
    }

    char line[100];
    fgets(line, 100, plik);

    while (fscanf(plik, "%u %f %f %f %f %f %f %f %f %f %f %f %f %f",
        &record.rok,
        &record.temp1,
        &record.temp2,
        &record.temp3,
        &record.temp4,
        &record.temp5,
        &record.temp6,
        &record.temp7,
        &record.temp8,
        &record.temp9,
        &record.temp10,
        &record.temp11,
        &record.temp12,
        &record.sredniaTeperatura) == 14)
    {
        record_t* rec;

        if (circ_buffer_put_record(&circBuff, &record) == -1) {
            while (rec = circ_buffer_put_record(&circBuff,&record)) {
                array_append_record(&array, rec);
            }
        }
    }

    ////wyswietlanie 
    //for (int i = 0; i < BUF_SIZE; i++)
    //{
    //    for (int j = 0; j < 14; j++)
    //    {
    //        printf("%u %f %f %f %f %f %f %f %f %f %f %f %f %f", tab[i][j]);
    //    }
    //}
}

 

komentarz 12 kwietnia 2020 przez j23 Mędrzec (194,920 p.)
edycja 12 kwietnia 2020 przez j23

Dlaczego zakomentowałeś wywołanie array_init? Ono musi tam być.

A i dodaj w array_init linię array->size = 0; (prawdopodobna przyczyna błędu; poprawiłem we wcześniejszych źródłach).

komentarz 12 kwietnia 2020 przez kaminie318 Bywalec (2,070 p.)

Meh, teraz linie niżej.

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

#define BUF_SIZE 3

typedef struct
{
    int rok;
    float temp1;
    float temp2;
    float temp3;
    float temp4;
    float temp5;
    float temp6;
    float temp7;
    float temp8;
    float temp9;
    float temp10;
    float temp11;
    float temp12;
    float sredniaTeperatura;
} record_t;

typedef struct {
    float** ptr;
    size_t size;
    size_t capacity;
} array_t;

typedef struct {
    record_t* buffer;
    uint8_t head;
    uint8_t tail;
} circ_buffer_t;


int8_t circ_buffer_put_record(circ_buffer_t* q, record_t* record)
{
    uint8_t head_temp = q->head + 1;

    if (head_temp == BUF_SIZE) 
        head_temp = 0;

    if (head_temp == q->tail)
        return -1;

    q->buffer[head_temp] = *record;
    q->head = head_temp;
    return 0;
}


record_t* circ_buffer_get_record(circ_buffer_t* q)
{
    if (q->head == q->tail) return NULL;
    ++q->tail;
    if (q->tail == BUF_SIZE) q->tail = 0;
    return q->buffer + q->tail;
}



void array_init(array_t* array)
{
    array->capacity = 10;
    array->size = 0;
    array->ptr = malloc(sizeof(float*) * array->capacity);

    for (int i = 0; i < array->capacity; ++i)
        array->ptr[i] = malloc(sizeof(float) * 14);
}


void array_append_record(array_t* array, record_t* rec)
{
    if (array->size + 1 == array->capacity) {

        size_t new_cap = array->capacity + 5;
        array->ptr = realloc(array->ptr, sizeof(float*) * new_cap);

        for (int i = array->capacity; i < new_cap; ++i)
            array->ptr[i] = malloc(sizeof(float) * 14);

        array->capacity = new_cap;
    }

    float* row = array->ptr[array->size++];     
    row[0] = rec->rok;                          //TERAZ TU
    row[1] = rec->temp1;
    row[2] = rec->temp2;
    row[3] = rec->temp3;
    row[4] = rec->temp4;
    row[5] = rec->temp5;
    row[6] = rec->temp6;
    row[7] = rec->temp7;
    row[8] = rec->temp8;
    row[9] = rec->temp9;
    row[10] = rec->temp10;
    row[11] = rec->temp11;
    row[12] = rec->temp12;
    row[13] = rec->sredniaTeperatura;
}

int main()
{
    // definiowanie tablicy
    array_t array;
    
    array_init(&array);

    record_t buffer[BUF_SIZE];
    circ_buffer_t circBuff = { buffer, 0, 0 };
    record_t record;

    FILE* plik = fopen("plik.txt", "r");
    if (plik == NULL) {
        printf("Plik ktorego szukasz nie istnieje");
        exit(0);
    }

    char line[100];
    fgets(line, 100, plik);

    while (fscanf(plik, "%u %f %f %f %f %f %f %f %f %f %f %f %f %f",
        &record.rok,
        &record.temp1,
        &record.temp2,
        &record.temp3,
        &record.temp4,
        &record.temp5,
        &record.temp6,
        &record.temp7,
        &record.temp8,
        &record.temp9,
        &record.temp10,
        &record.temp11,
        &record.temp12,
        &record.sredniaTeperatura) == 14)
    {
        record_t* rec;

        if (circ_buffer_put_record(&circBuff, &record) == -1) {
            while (rec = circ_buffer_put_record(&circBuff,&record)) 
            {
                array_append_record(&array, rec);
            }
        }
    }

    ////wyswietlanie 
    //for (int i = 0; i < BUF_SIZE; i++)
    //{
    //    for (int j = 0; j < 14; j++)
    //    {
    //        printf("%u %f %f %f %f %f %f %f %f %f %f %f %f %f", tab[i][j]);
    //    }
    //}
    return 0;
}

 

komentarz 13 kwietnia 2020 przez j23 Mędrzec (194,920 p.)

Z linii 77 wywal  + 1 (nie wiem, po co to tam dałem).

komentarz 13 kwietnia 2020 przez kaminie318 Bywalec (2,070 p.)
To samo :(
komentarz 13 kwietnia 2020 przez j23 Mędrzec (194,920 p.)
edycja 13 kwietnia 2020 przez j23

Dobra popraw linię 144 - tam powinno być wywołanie circ_buffer_get_record.  Za linią 146 dodaj wywołanie circ_buffer_put_record(&circBuff, &record);

Tak to jest, jak się daje na szybko pisany kod bez testowania. W sumie Ty też powinieneś być bardziej uważny, dodałeś parametr zamiast zmienić nazwę funkcji.

komentarz 13 kwietnia 2020 przez kaminie318 Bywalec (2,070 p.)
edycja 13 kwietnia 2020 przez kaminie318

Linia 144 też mi nie pasowała. Po dodaniu wywołania za 146 linią też nie działa, zakomentowałem tą linie i gra, ale to chyba nie jest dobre. Chciałem zobaczyć jak będzie wyświetlać na ekran, i gubi dane.

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

#define BUF_SIZE 3

typedef struct
{
    int rok;
    float temp1;
    float temp2;
    float temp3;
    float temp4;
    float temp5;
    float temp6;
    float temp7;
    float temp8;
    float temp9;
    float temp10;
    float temp11;
    float temp12;
    float sredniaTeperatura;
} record_t;

typedef struct {
    float** ptr;
    size_t size;
    size_t capacity;
} array_t;

typedef struct {
    record_t* buffer;
    uint8_t head;
    uint8_t tail;
} circ_buffer_t;


int8_t circ_buffer_put_record(circ_buffer_t* q, record_t* record)
{
    uint8_t head_temp = q->head + 1;

    if (head_temp == BUF_SIZE) 
        head_temp = 0;

    if (head_temp == q->tail)
        return -1;

    q->buffer[head_temp] = *record;
    q->head = head_temp;
    return 0;
}


record_t* circ_buffer_get_record(circ_buffer_t* q)
{
    if (q->head == q->tail) return NULL;
    ++q->tail;
    if (q->tail == BUF_SIZE) q->tail = 0;
    return q->buffer + q->tail;
}



void array_init(array_t* array)
{
    array->capacity = 10;
    array->size = 0;
    array->ptr = malloc(sizeof(float*) * array->capacity);

    for (int i = 0; i < array->capacity; ++i)
        array->ptr[i] = malloc(sizeof(float) * 14);
}


void array_append_record(array_t* array, record_t* rec)
{
    if (array->size == array->capacity) {

        size_t new_cap = array->capacity + 5;
        array->ptr = realloc(array->ptr, sizeof(float*) * new_cap);

        for (int i = array->capacity; i < new_cap; ++i)
            array->ptr[i] = malloc(sizeof(float) * 14);

        array->capacity = new_cap;
    }

    float* row = array->ptr[array->size++];     
    row[0] = rec->rok;                          //TERAZ TU
    row[1] = rec->temp1;
    row[2] = rec->temp2;
    row[3] = rec->temp3;
    row[4] = rec->temp4;
    row[5] = rec->temp5;
    row[6] = rec->temp6;
    row[7] = rec->temp7;
    row[8] = rec->temp8;
    row[9] = rec->temp9;
    row[10] = rec->temp10;
    row[11] = rec->temp11;
    row[12] = rec->temp12;
    row[13] = rec->sredniaTeperatura;
}

int main()
{
    // definiowanie tablicy
    array_t array;
    
    array_init(&array);

    record_t buffer[BUF_SIZE];
    circ_buffer_t circBuff = { buffer, 0, 0 };
    record_t record;

    FILE* plik = fopen("plik.txt", "r");
    if (plik == NULL) {
        printf("Plik ktorego szukasz nie istnieje");
        exit(0);
    }

    char line[100];
    fgets(line, 100, plik);

    while (fscanf(plik, "%u %f %f %f %f %f %f %f %f %f %f %f %f %f",
        &record.rok,
        &record.temp1,
        &record.temp2,
        &record.temp3,
        &record.temp4,
        &record.temp5,
        &record.temp6,
        &record.temp7,
        &record.temp8,
        &record.temp9,
        &record.temp10,
        &record.temp11,
        &record.temp12,
        &record.sredniaTeperatura) == 14)
    {
        record_t* rec;

        if (circ_buffer_put_record(&circBuff, &record) == -1) {
            while (rec = circ_buffer_get_record(&circBuff,&record)) 
            {
                array_append_record(&array, rec);
               // circ_buffer_put_record(&circBuff, &record);
                //while(rec++)
                printf("%u %f %f %f %f %f %f %f %f %f %f %f %f %f\n", rec->rok,rec->temp1,rec->temp2, rec->temp3, rec->temp4, rec->temp5, 
                             rec->temp6,rec->temp7, rec->temp8,rec->temp9, rec->temp10, rec->temp11, rec->temp12,rec->sredniaTeperatura);
            }
        }
    }

    return 0;
}

 

komentarz 14 kwietnia 2020 przez j23 Mędrzec (194,920 p.)

Pisałem, żebyś był bardziej uważny. Gdzie circ_buffer_get_record ma dwa parametry?

Po dodaniu wywołania za 146 linią

Pomyliłem się (znowu), powinno być za 147, czyli za pętlą while ;)

Podobne pytania

0 głosów
1 odpowiedź 97 wizyt
pytanie zadane 22 maja 2023 w C i C++ przez Dani Obywatel (1,450 p.)
+1 głos
1 odpowiedź 793 wizyt
pytanie zadane 23 kwietnia 2021 w C i C++ przez Mavimix Dyskutant (8,390 p.)
+1 głos
2 odpowiedzi 316 wizyt
pytanie zadane 10 marca 2021 w C i C++ przez huberos23 Nowicjusz (170 p.)

92,579 zapytań

141,432 odpowiedzi

319,663 komentarzy

61,964 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.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...