Skocz do zawartości
Zamknięcie Forum PC LAB

Szanowny Użytkowniku,

Informujemy, że za 30 dni tj. 30 listopada 2024 r. serwis internetowy Forum PC LAB zostanie zamknięty.

Administrator Serwisu Forum PC LAB - Ringier Axel Springer Polska sp. z o.o. z siedzibą w Warszawie: wypowiada całość usług Serwisu Forum PC LAB z zachowaniem miesięcznego okresu wypowiedzenia.

Administrator Serwisu Forum PC LAB informuje, że:

  1. Z dniem 29 listopada 2024 r. zakończy się świadczenie wszystkich usług Serwisu Forum PC LAB. Ważną przyczyną uzasadniającą wypowiedzenie jest zamknięcie Serwisu Forum PC LAB
  2. Dotychczas zamowione przez Użytkownika usługi Serwisu Forum PC LAB będą świadczone w okresie wypowiedzenia tj. do dnia 29 listopada 2024 r.
  3. Po ogłoszeniu zamknięcia Serwisu Forum od dnia 30 października 2024 r. zakładanie nowych kont w serwisie Forum PC LAB nie będzie możliwe
  4. Wraz z zamknięciem Serwisu Forum PC LAB, tj. dnia 29 listopada 2024 r. nie będzie już dostępny katalog treści Forum PC LAB. Do tego czasu Użytkownicy Forum PC LAB mają dostęp do swoich treści w zakładce "Profil", gdzie mają możliwość ich skopiowania lub archiwizowania w formie screenshotów.
  5. Administrator danych osobowych Użytkowników - Ringier Axel Springer Polska sp. z o.o. z siedzibą w Warszawie zapewnia realizację praw podmiotów danych osobowych przez cały okres świadczenia usług Serwisu Forum PC LAB. Szczegółowe informacje znajdziesz w Polityce Prywatności

Administrator informuje, iż wraz z zamknięciem Serwisu Forum PC LAB, dane osobowe Użytkowników Serwisu Forum PC LAB zostaną trwale usunięte ze względu na brak podstawy ich dalszego przetwarzania. Proces trwałego usuwania danych z kopii zapasowych może przekroczyć termin zamknięcia Forum PC LAB o kilka miesięcy. Wyjątek może stanowić przetwarzanie danych użytkownika do czasu zakończenia toczących się postepowań.

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