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

Użycie pliku fstream jako argumentu funkcji

VPS Starter Arubacloud
0 głosów
1,724 wizyt
pytanie zadane 2 grudnia 2016 w C i C++ przez Riddick Bywalec (2,600 p.)

Witam, piszę funkcję która ma otwierać plik tekstowy, wyszukać odpowiedni kod rozpoznawczy ustalony przeze mnie, wczytać każdą linijkę tekstu do zmiennej puki nie napotka kodu informującego o zakończeniu danego bloku tekstu i zwrócenie tekstu ze zmiennej, który zamierzam wykorzystać przez inną funkcję. Problem polega na tym (a raczej tak mi się wydaje bo nie rozumiem do końca błędów z kompilatora), że nie mogę użyć jako argumentu funkcji zmiennej typu fstream. Sama funkcja kompiluje się lecz gdy jej użyję sypie mi się mnóstwo błędów. Przeszukałem już chyba cały internet, robiłem sobie przerwę w pracy i nic nie mogłem znaleźć co mogłoby być nie tak.

Oto moja funkcja

string read(fstream file, string name, string type, string nb) {
	file.open(name.c_str(), ios::out);
	if(file.good()==true) {
		string text = "#"+type+"# "+nb;
		string text2;
		string text3;
		if(!file.fail()) {
			if(getline(file, text2)) {
				if(text==text2) {
					do {
						getline(file, text2);
						text3 = text3+text2;
					}while(text2 != "#end#");
					file.close();
					return text3;
				}
			}
		} else {
			system("cls");
			cout<<"Error #02\n";
			system("Pause");
			file.close();
			exit(0);
		}
	} else {
		system("cls");
		cout<<"Error #01\n";
		system("Pause");
		file.close();
		exit(0);
	}
	return 0;
}

A to jej wywołanie

cout<<read(language, "Language\Polski.txt", "text", "1");

A kompilator wywala mi takie błędy

||=== Build: Debug in Terminal RPG (compiler: GNU GCC Compiler) ===|
C:\Users\Marci\OneDrive\Projekty\Terminal RPG\Terminal RPG Project\main.cpp||In function 'int main()':|
C:\Users\Marci\OneDrive\Projekty\Terminal RPG\Terminal RPG Project\main.cpp|19|warning: unknown escape sequence: '\P'|
C:\Program Files (x86)\CodeBlocks\MinGW\lib\gcc\mingw32\4.9.2\include\c++\bits\ios_base.h|786|error: 'std::ios_base::ios_base(const std::ios_base&)' is private|
C:\Program Files (x86)\CodeBlocks\MinGW\lib\gcc\mingw32\4.9.2\include\c++\bits\basic_ios.h|66|error: within this context|
C:\Program Files (x86)\CodeBlocks\MinGW\lib\gcc\mingw32\4.9.2\include\c++\fstream|779|note: synthesized method 'std::basic_ios<char>::basic_ios(const std::basic_ios<char>&)' first required here |
C:\Program Files (x86)\CodeBlocks\MinGW\lib\gcc\mingw32\4.9.2\include\c++\streambuf|802|error: 'std::basic_streambuf<_CharT, _Traits>::basic_streambuf(const std::basic_streambuf<_CharT, _Traits>&) [with _CharT = char; _Traits = std::char_traits<char>]' is private|
C:\Program Files (x86)\CodeBlocks\MinGW\lib\gcc\mingw32\4.9.2\include\c++\fstream|72|error: within this context|
C:\Program Files (x86)\CodeBlocks\MinGW\lib\gcc\mingw32\4.9.2\include\c++\fstream|779|note: synthesized method 'std::basic_filebuf<char>::basic_filebuf(const std::basic_filebuf<char>&)' first required here |
C:\Users\Marci\OneDrive\Projekty\Terminal RPG\Terminal RPG Project\main.cpp||In function 'int main()':|
C:\Users\Marci\OneDrive\Projekty\Terminal RPG\Terminal RPG Project\main.cpp|19|note: synthesized method 'std::basic_fstream<char>::basic_fstream(const std::basic_fstream<char>&)' first required here |
C:\Users\Marci\OneDrive\Projekty\Terminal RPG\Terminal RPG Project\game.h|44|error:   initializing argument 1 of 'std::string readi(std::fstream, std::string, std::string, std::string)'|
||=== Build failed: 5 error(s), 1 warning(s) (0 minute(s), 0 second(s)) ===|

Sam już sobie z tym nie poradzę. Proszę o pomoc.

komentarz 2 grudnia 2016 przez Riddick Bywalec (2,600 p.)
edycja 2 grudnia 2016 przez Riddick
Próbowałem zapisać to jako fstream& file i co prawda nie mam żadnych błędów kompilacji ale program przestaje działać na starcie
komentarz 2 grudnia 2016 przez maly Nałogowiec (37,190 p.)

Sprawdzasz startowy tag tylko w pierwszej linii.
Jeśli w pliku zabraknie końcowego taga to pętla będzie działać w nieskończoność.

string line;
string result;
bool start = false;

while(getline(file, line))
	if(start)
		if(line == "#end#")
			return result;
		result += line;
	else if(line == start_tag)
		start = true;

 

komentarz 2 grudnia 2016 przez Riddick Bywalec (2,600 p.)
Rzeczywiście nie pomyślałem o tym. Zakładałem, że końcowy tag po prostu będzie i tyle a nie pomyślałem, że program może uznać to jako błąd logiczny. Jednak zrobię to po swojemu i dodam dodatkowego ifa który kończy pętle gdy pętla napotka koniec pliku lub licznik dojdzie do dwudziestu bo mój projekt nie przewiduje tekstu większego niż jest w stanie wyświetlić konsola bez scrolla.
komentarz 2 grudnia 2016 przez Riddick Bywalec (2,600 p.)
edycja 2 grudnia 2016 przez Riddick

Działaaaaa.

Dzięki wszystkim za pomoc. Kod przerobiłem w ten sposób

void err(string nr) {
    system("cls");
    cout<<"Error #"+nr+"\n";
    system("Pause");
    exit(0);
}
string read(fstream& file, string name, string type, string nb) {
    file.open(name.c_str(), ios::in);
    if(file.good()==true) {
        string text = "#"+type+"# "+nb;
        string text2;
        string text3;
        while(!file.fail()) {
            getline(file, text2);
            if(text2 == text) {
                for(int i = 0; i<=20; i++) {
                    getline(file, text2);
                    if(text2 == "#end#") {
                        file.close();
                        return text3;
                    }
                    if(file.fail()) {
                        file.close();
                        err("f4");
                    };
                    text3 += text2;
                }
                return text3;
                file.close();
                err("f3");
            }
        }
        file.close();
        err("f2");
    } else {
        file.close();
        err("f1");
    }
}

 

komentarz 2 grudnia 2016 przez Riddick Bywalec (2,600 p.)
Dowiedziałem się, że nie mogę użyć return 0 w funkcji zwracającej string. Ale to niewiele pomogło. Program coś wyświetla na ekranie problem w tym że to są jakieś losowe litery i wyświetla je bez przerwy puki program znów nie przestanie działać.

2 odpowiedzi

+1 głos
odpowiedź 2 grudnia 2016 przez siof Gaduła (3,560 p.)
Do funkcji read przekazujesz obiekt fstream przez wartość dlatego sie sypie bo nie może użyć konstruktora kopiującego bo jest on prywatny (to wynika z tych błędów kompilacyjnych). Spróbuj zmienić aby obiekt fstream był przesyłany przez referencję (zmiana w funkcji na 'fstream & file' wydaje sie że powinna załatwić sprawę)
+1 głos
odpowiedź 2 grudnia 2016 przez criss Mędrzec (172,590 p.)
Na pewno funkcja nie może przyjmować po prostu obiektu std::fstream, bo musiałaby by go skopiować, a fstream nie ma konstruktora kopiującego (od c++11 =delete, przy wcześniejszych standardach po postu jest prywatny) o czym z resztą informuje cie kompilator. Także wszystko co musisz zrobić, to zapobiec kopiowaniu, czyli przekazywać przez referencje albo wskaźnik.

Podobne pytania

0 głosów
1 odpowiedź 308 wizyt
0 głosów
3 odpowiedzi 876 wizyt
pytanie zadane 13 grudnia 2015 w C i C++ przez Sedi Stary wyjadacz (10,200 p.)
0 głosów
1 odpowiedź 213 wizyt

92,452 zapytań

141,261 odpowiedzi

319,074 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!

...