Skocz do zawartości

Temat został przeniesiony do archiwum

Ten temat przebywa obecnie w archiwum. Dodawanie nowych odpowiedzi zostało zablokowane.

informatyk2000

Pomocy, problem z klasą w c++.

Rekomendowane odpowiedzi

Dzień dobry,

 

Mam problem. Napisalem kod, klasę i starałem się rozwinac go bardziej, az do momentu, w którym napotkałem przeszkodę. Mialem zamiar przeciążyć operator>> dla fstream, aby wczytywac kolejne wyrazy z pliku tekstowego do mojej klasy, operator mial pomijac podczas wczytywania znak '-', a po napotkaniu znaku '/' mial nie wypisywac reszty wyrazu, ale napotykam na błąd i nie wiem w jaki sposób go rozwiązać. Wszystko mam dodac do vectora. Dodam, ze gdy zmienialem funkcje w operatorze przeciążającym to działał on, lecz z niewiadomych przyczyn nie spelnial swojego zadania.(Tak, kod na pewno byl poprawny.) Załączam moje pliki(nagłowkowy, z funkcjami oraz główny oraz zdjecie bledu).

#pragma once

#include <iostream>
#include <string>
#include  <vector>
#include <cstring>
#include <fstream>

using namespace std;


class cNapis {
char napis_[1000];
public:
cNapis() :napis_("nie wprowadziles zadnego tekstu") {}
cNapis(string napis);
void show() {cout << napis_;}
friend std::istream& operator>>(std::istream& str, cNapis &napis);
friend std::ostream& operator<<(std::ostream& str, const cNapis &napis);

friend std::fstream& operator>>(std::fstream& str, cNapis &napis);
};

 

#include "cNapis.h"
int main()
{
cNapis napis;
cNapis napis2 ("ala ma kota");
cin >> napis;
cout << napis;
cout << endl << endl;
cout << "---------------Druga czesc zadania------------------" << endl;
vector<cNapis> napisy;
fstream plik;
plik.open("polish.txt", ios::in);
	while (!plik.eof()) {
		cNapis tmp;
		plik >> tmp;
		tmp.show();
		napisy.push_back(tmp);
	}
for (auto i = napisy.begin(); i != napisy.end(); i++)
{
	(*i).show();
	cout << endl;
}




system("pause");
return 0;

}


#include "cNapis.h"

cNapis::cNapis(string napis)
{
int i = 0;
for (i; i < napis.length(); i++)
{
	napis_[i] = napis[i];
}
napis_[i] = '\0';
}

istream& operator>>(istream& str, cNapis &z)
{
str >> z.napis_;
return str;
}

ostream& operator<<(ostream& str, const cNapis &napis)
{
str << napis.napis_;
return str;
}

fstream& operator>>(fstream& str, cNapis &napis)
{
str >> napis.napis_;
cNapis napis12;

for (int i = 0; napis.napis_[i] != '\0';i++)
{
	do{
		if (napis.napis_[i] != '-')
		{
			napis12.napis_[i] = napis.napis_[i];
		}
	} while (napis.napis_[i] != '/');	

}
str >> napis12.napis_;
return str;
}

 

https://imgur.com/gHtVLhi

 

moge rowniez wyslac jak powinien wyglądać use case. Oto on:

1. Stworzyć klasę cNapis

 

Use case:

 

cNapis n("ala ma kota"), tekst;

 

cin>>tekst;

 

cNapis tekst_polaczany = n + tekst;

 

cout>>tekst_polaczany;

 

2. Dodać do klasy napis opeartor >> do wczytywania z klasy fstream pojedynczych wyrazów z pliku dict (https://raw.githubusercontent.com/titoBouzout/Dictionaries/master/Polish.dic) operator ten powinien ingorować wszystkie znak '-' i elemeny znajdujące za znakiem '/'

 

Usecase:

 

std::vector<cNapis> napisy;

 

std::fstream plik("Polish.dic");

 

while(!plik.eof()){

 

cNapis tmp;

 

plik>>tmp;

 

napisy.push_back(tmp);

 

}

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

możesz np. użyć try/catch, żeby zobaczyć co to za wyjątek krytyczny się pojawia

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Visual wszystko Ci podpowiedział - poleciał std::bac_alloc, bo std::vector nie mógł zaalokować więcej pamięci. Zwróc uwage, że jeden obiekt klasy cNapis to prawie 1kB (1000 char-ów x 1 bajt), a wyrazów w tym plików masz pierdyliard. Sprawdź ile może mieć maksymalnie znaków jeden wyraz w słowniku i ogranicz rozmiar tablicy.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

W klasie masz membera char napis_[1000], więc jest to tablica 1000 char-ów (tablica na 1000 znaków). Na pewno tylu nie potrzebujesz, czyli możesz zmniejszyć rozmiar tej tablicy np. do 50 znaków - char napis_[50].

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Nieobsłużony wyjątek w lokalizacji 0x776BC41F w Projekcik.exe: wyjątek języka Microsoft C++: std::bad_alloc w lokalizacji pamięci 0x0014EDB0. Oto błąd który otrzymałem po zmniejszeniu do 50

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

jakiej wielkości jest ten plik polish.txt?

 

edyta - dobra znalazłem - 300k wyrazów

więc nawet dla 1kB bufora to tylko 300MB pamięci, dla 50B to 15MB więc dziwne, że leci bad alloc

 

dodatkowo

fstream& operator>>(fstream& str, cNapis &napis)

 

raczej nie jest OK jeśli ma robić to co było opisane....

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

O kurczę... Dziękuję bardzo!

A moglbym prosić o pomoc, bo nie za bardzo wiem, co zrobilem nie tak :(

Z góry dziękuję!

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Witam ponownie. Napisalem kod jeszcze raz. Mógłby mi ktos powiedziec czemu wywala bład w miejscu w ktorym wywala. Przesylam caly kod.

#include <iostream>
#include <vector>
#include <fstream>
#include <algorithm>
#include <cstring>

using namespace std;

class cNapis {
char napis_[1000];
public:

	cNapis():napis_("..."){}
	cNapis(string napis) {
		int i = 0;
		for ( i ; i != napis.length(); i++)
		{
			napis_[i] = napis[i];
		}

		napis_[i] = '\0';
		/*for (int i = 0; i!=strlen(napis_); i++)
		{
			cout << napis_[i];
		}*/
	}
	friend istream& operator>>(istream& str, cNapis &z)
	{
		str >> z.napis_;
		return str;
	}
	cNapis operator+(cNapis napis)
	{
		cNapis k;
		strcpy_s(k.napis_, this->napis_);
		strcat_s(k.napis_, " ");
		strcat_s(k.napis_, napis.napis_);
		return k;
	}
	friend ostream& operator<<(ostream& str, const cNapis &napis)
	{
		str << napis.napis_;
		return str;
	}
	cNapis zwroc()
	{
		cNapis nap;
		int i = 0;
				for (i; napis_[i] != '\0'; i++)
				{
					if (napis_[i] != '/')
					{
						if (napis_[i] != '-')
						{
							nap.napis_[i] = napis_[i];
						}
					}
					else
					{
						nap.napis_[i] = '\0';
						break;
					}
				}
		return nap;
	}
	friend fstream& operator>>(fstream& str, cNapis &napis)
	{
		str >> napis.napis_;
			return str;
	}
	void show()
	{
		cout<<napis_;
	}
	cNapis pok(cNapis &napis)
	{
		return napis;
	}
	bool operator== (cNapis z) const
	{
		int acc = 0;
		for (int i = 0; '0' != strlen(napis_); i++)
		{
			if (napis_[i] == z.napis_[i])
				acc++;
		}
		if (acc==strlen(z.napis_))
			return true;
		else
			return false;
	}
};
class cPredykat {
cNapis pred_class;
public:
cPredykat(string napis)
{
	pred_class = napis;
}
void set_prog(const cNapis z) { pred_class= z; }
//	cNapis pred_class() { return pred_class; }
bool operator()(cNapis& napis){
	return napis == pred_class;
}


};

int main()
{
cNapis n("ala ma kota"), tekst;
cin>>tekst;
cNapis tekst_polaczany = n + tekst;
cout << tekst_polaczany;
cout << endl << "----------Drugie zadanie-----------------" << endl;
vector<cNapis> napisy;

fstream plik("polish.txt");

while (!plik.eof()) {

	cNapis tmp;
	plik >> tmp;
	cNapis a=tmp.zwroc();
	napisy.push_back(a);

}
cout << "Dane zostaly wczytane." << endl;
/*	for (auto it = napisy.begin(); it != napisy.end(); it++)
{
	(*it).show();
	cout << endl;
}*/
cout << "--------------Trzecie zadanie.---------------" << endl;
cPredykat pred("atrim");

auto itr = napisy.begin();

while (itr != napisy.end()) {

	itr = find_if(itr, napisy.end(), pred);

	if (itr != napisy.end()) {

		std::cout << *itr << std::endl;

		itr++;

	}

}


system("pause");
return 0;
}

 

Proszę o przekopiowanie kodu do własnego kompilatora i udzielenie mi odpowiedzi. Z góry dziekuje!!!

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Nie chce mi się szukać ani preparować stosownego pliku, ale pierwsza rzecz - nie sprawdzasz w ogóle, czy udało się otworzyć plik.

Bez tego pętla czytająca dane z pliku ładuje śmieci do vectora bez końca.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Sprawdzilem to już wcześniej, żadna pomoc

Dobrze poradził.

        if (plik.is_open())
        {
            while (!plik.eof()) {
    
                    cNapis tmp;
                    plik >> tmp;
                    napisy.push_back(tmp.zwroc()); 
            }
            cout << "Dane zostaly wczytane." << endl;
        }

Na wszelki wypadek dodatkowo zmniejsz rozmiar tej tablicy char-ów.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Z tym juz nie mam problemu. Problem pojawil sie w zadaniu 3, wyraznie zaznaczone przez "----------Trzecie zadanie----------'. Bład jest wskazywany w bool operatorze= i kod błędu wyglada nastepujaco: Zgłoszono wyjątek: naruszenie dostępu do odczytu.

this było 0x1E71112.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Możesz wytłumaczyć filozofię stojącą za tą linijką?:

for (int i = 0; '0' != strlen(napis_); i++)

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

  • Ostatnio przeglądający   0 użytkowników

    Brak zarejestrowanych użytkowników przeglądających tę stronę.

×
×
  • Dodaj nową pozycję...