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

struktura wskaźniki przekazanie do funkcji i pliku

Object Storage Arubacloud
0 głosów
291 wizyt
pytanie zadane 15 stycznia 2021 w C i C++ przez janusz_cpp Nowicjusz (120 p.)

Witam

Mam fragment kodu, w ktorym staram sie pobrac linie z pliku , obciac niechciane znaki, zapisać do stringa, zapisac do struktury i ponownie wczytac linię, niestety pogubiłem sie ze wskaźnikami do tablic itp.

pierwsza petla wykonuje sie a na drugiej wywala sie program. pierwsza wpisana dana jest ok.

 

struct Book {

char id;
string
    title,
    author,
    year ;
int lp;
};
....
void wczytaj(Book *tablica[], int &dlugosc){

   char nazwaPliku[80];
    string komorka[30];
    ifstream plik_bib;
    string linia;
    char linia_pom[100];
    int pom=0,pom2=0;

    Book* dane_art;
    dane_art=new Book;

    cout <<"Podaj nazwe pliku: ";
    cin >> nazwaPliku;

    plik_bib.open( nazwaPliku, ios::in );

    if(!plik_bib){
        cout<<"Nieudane otwarcie pliku "<<nazwaPliku<<" "<<endl;
        exit(1);
    }
    do
    {
        tablica[dlugosc] = new Book;
        *tablica[dlugosc] = *dane_art;

    for(int i=0;!plik_bib.eof();i++) {
        getline(plik_bib,linia);
        if (sprawdz(linia,"@book")==1) {
            pom++;

            tablica[pom-1]->lp=pom;  // tutaj wywala sie druga pętla
            zapisz(tablica,pom);  // zapis do pliku
            cout << tablica[pom-1]->lp <<endl;
            for (int i=0; i<=pom;i++){
                cout <<tablica[i]->lp << endl;
            }
        }
        if ((sprawdz(linia,"author=")==1)||(sprawdz(linia,"author =")==1)) {
            pom2=szukajZnak(linia,'"');
            linia.erase(0,pom2+1);
            linia.erase(linia.end()-2,linia.end());
            tablica[pom-1]->author=linia;
            zapisz(tablica,pom);
            cout << linia << endl;
        }
...
 while(!plik_bib.eof());
    delete dane_art;
    delete tablica;

int main()
{
const int MAX_REKORD=100;
Book* dane_plik[MAX_REKORD];
int dlugosc=10;
...
wczytaj(dane_plik,dlugosc);
...
for(int i=0;i<dlugosc;i++) {
		delete dane_plik[i];
    return 0;

Prawdopodobnie coś robie nie tak z pamiecią. Jestem początkujący :)

komentarz 15 stycznia 2021 przez j23 Mędrzec (194,920 p.)

Straszny chaos i kwiatki typu:

pom++;
tablica[pom - 1]->lp = pom;
cout << tablica[pom - 1]->lp << endl;

Po co zwiększasz indeks, skoro i tak później musisz się cofnąć o jeden?


Pokaż przykładową zawartość pliku z danymi.

komentarz 15 stycznia 2021 przez janusz_cpp Nowicjusz (120 p.)
@book{JCG,
author= "Jean Ch. Grange",
year= "1999",
title= "Lot bocianow",
publisher= "PWN Warszawa"
}
@book{SiB,
title = "Rany kamieni",
year = "2011",
author = "Simon Beckett"
}
komentarz 15 stycznia 2021 przez janusz_cpp Nowicjusz (120 p.)
pom to nr pozycji w bibliotece (liczba porządkowa startuje od 1) a powiązany [pom-1] to indeks w tablicy (startuje od 0)
komentarz 15 stycznia 2021 przez j23 Mędrzec (194,920 p.)

Ja wiem, o co Ci tam chodzi. Tylko po co zwiększasz pom, skoro wiesz, że zaraz będziesz potrzebował starej wartości w kilku miejscach?

tablica[pom]->lp = pom + 1; 
cout << tablica[pom]->lp << '\n';
++pom;

Niewielka różnica, ale kodu mniej, analizuje się prościej itd.

BTW,  po co to lp, przecież to jest samo co pozycja książki w tablicy plus jeden?


Ten format to sobie sam wymyśliłeś czy jak?

Co to i po co te JCG i SiB?

komentarz 15 stycznia 2021 przez janusz_cpp Nowicjusz (120 p.)
wskazówki zastosuje, a format jest specjalnie skomplikowany żeby było trudniej :)

bardziej chcialem skupic sie na przekazywaniu wartości do struktury, bo to słabo działa.

nie chce mi wpisywać stringa "linia" do struktury, dane int wpisuje bez problemu

podejrzewam też problem z alokacją pamięci, a może przekazaniem wskazników struktury do funkcji ?
komentarz 16 stycznia 2021 przez j23 Mędrzec (194,920 p.)
edycja 16 stycznia 2021 przez j23

Dobra, tu masz przykładowy kod parsera tego formatu:

#include <iostream>
#include <sstream>
#include <sstream>
#include <utility>
#include <tuple>

...

bool expect(std::istream& is, char c)
{
	if((is >> std::ws).peek() == c) {
		is.ignore();
		return true;
	}
	
	return false;
}

std::string readAlNum(std::istream& is)
{
	int c;
	std::string s;
	
	is >> std::ws;    

	while(c = is.peek(), c != EOF && isalnum(c)) {
		s += static_cast<char>(c);
		is.ignore();
	}
	
	return s;
}

std::string readQuoted(std::istream& is)
{
	int c;
	int prev_c;
	std::string s;
	
	is >> std::ws;    

	if(!expect(is, '"')) return s;

	while(c = is.peek(), c != EOF) {
		if(c == '"') {
			if(prev_c != '\\') {
				is.ignore();
				return s;
			}
		}

		if(prev_c == '\\' && c != '"' && c != '\\') s += '\\';
		if(c != '\\') s += c;
		prev_c = c;
		is.ignore();
	}
	
	return s;
}

std::pair<std::string, std::string> parseValue(std::istream& is) 
{
	std::string name = readAlNum(is);
	std::string value;

	if(expect(is, '=')) {
		value =  readQuoted(is);
	}
	
	return { name, value };
}

std::pair<bool, Book> parseBook(std::istream& is)
{
	if(!expect(is, '@') || readAlNum(is) != "book" || !expect(is, '{')) return { false, {} };
	
	readAlNum(is);

	Book book;
	
	while(expect(is, ',')) {
		auto res = parseValue(is);
		//tu wypełniasz book wartościami, gdzie res.first to nazwa, res.second - wartość		
	}

	return { expect(is, '}'), book };
}


int main(void)
{
	std::ifstream is(...);
	bool ok;
	Book book;

	while (std::tie(ok, book) = parseBook(is), ok) {
		// tu dodajesz book do np. vectora
	}
}

Zwróć uwagę na podział na funkcje - każda odpowiada za parsowanie swojego fragmentu formatu.

No i nie ma tu new i delete...

Jak by coś było niejasne, pytaj ;)

komentarz 16 stycznia 2021 przez janusz_cpp Nowicjusz (120 p.)
troche dla mnie skomplikowane jak na moją wiedzę ale dziękuję ogólnie wiem o co chodzi,na początek nie mogę dojsc co to jest "is"?
komentarz 16 stycznia 2021 przez j23 Mędrzec (194,920 p.)

is to strumień, z którego czytany jest plik. W main jest zdefiniowany i przekazywany w przez referencję w parametrach funkcji.

Zaloguj lub zarejestruj się, aby odpowiedzieć na to pytanie.

Podobne pytania

0 głosów
2 odpowiedzi 345 wizyt
pytanie zadane 23 czerwca 2021 w C i C++ przez Eriss69 Gaduła (4,470 p.)
0 głosów
1 odpowiedź 124 wizyt
pytanie zadane 12 czerwca 2020 w C i C++ przez dominik195k Obywatel (1,030 p.)
+1 głos
2 odpowiedzi 651 wizyt
pytanie zadane 8 grudnia 2018 w C i C++ przez MAXIM7 Obywatel (1,990 p.)

92,634 zapytań

141,505 odpowiedzi

319,883 komentarzy

62,015 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!

...