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

Wczytywanie do bufora kołowego

VPS Starter Arubacloud
0 głosów
564 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 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ź 92 wizyt
pytanie zadane 22 maja 2023 w C i C++ przez Dani Obywatel (1,420 p.)
+1 głos
1 odpowiedź 726 wizyt
pytanie zadane 23 kwietnia 2021 w C i C++ przez Mavimix Dyskutant (8,390 p.)
+1 głos
2 odpowiedzi 291 wizyt
pytanie zadane 10 marca 2021 w C i C++ przez huberos23 Nowicjusz (170 p.)

92,452 zapytań

141,262 odpowiedzi

319,077 komentarzy

61,854 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

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 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!

...