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

Wielokrotne czytanie tekstu - problem powrotu pozycji odczytu

VPS Starter Arubacloud
0 głosów
197 wizyt
pytanie zadane 29 sierpnia 2016 w C i C++ przez plkpiotr Stary wyjadacz (12,420 p.)

Program ma za zadanie odczytywać kilkukrotnie ten sam plik tekstowy "wiersz.txt" i za każdym razem konwertować ten tekst na tablicę znaków (odpowiednio bez znaku nowego wiersza, bez białych znaków, bez liczb itp). To w jaki sposób ma to zrobić określone jest przez kolejny plik tekstowy o nazwie "polecenia.txt". Mój kod jest na ukończeniu, wydawać by się mogło, że działa poprawnie jednak podczas testu okazuje się, że działa poprawnie tylko podczas pierwszego przeczytania pliku  "wiersz.txt", w odróżnieniu od kolejnych prób.

Domyślam się, że chodzi tu o pozycję odczytu, która po przejściu przez cały plik tekstowy znajduje się na jego końcu i nie wraca na początek... Próbowałem za każdym razem otwierać i zamykać uchwyt do pliku ifstream odczyt, później natomiast odczytywać znaki w pętli while do przedostatniej pozycji i powrót za pomocą funkcji seekg() w metodzie pobierzPlik(), jednak i to nie działa, przez co jestem bezradny, cały kod zamieszczam poniżej, lecz jeżeli komuś to pomoże wrzucam też gotowy projekt code::blocks w linku:
 

//==================================================
// Nazwa          : main.cpp
//==================================================

#include "napisy.h"

int main() {
	ifstream komendy;
	ifstream odczyt;
	ofstream zapis;
	string kmnd;
	string dczt;
	string zps;

	string operacja;
	string slowa;

	Tekst przykladowy;
	unsigned short licznik = 0;

	kmnd = "polecenia.txt";
//	cout << "Napisz ponizej pelna nazwe pliku z komendami:" << endl;
//	cin >> kmnd;
	komendy.open(kmnd.c_str());
	okreslOtwarcie(komendy);

	dczt = "wiersz.txt";
//	cout << "Napisz ponizej pelna nazwe pliku do odczytu:" << endl;
//	cin >> dczt;
	odczyt.open(dczt.c_str());
	okreslOtwarcie(odczyt);

	zps = "zakonczenie.txt";
//	cout << "Napisz ponizej pelna nazwe pliku do zapisu:" << endl;
//	cin >> zps;
	zapis.open(zps.c_str());
	okreslOtwarcie(zapis);

	cout << "Oryginalny tekst:" << endl;

	while (!komendy.eof()) {
           getline(komendy,operacja);
		if (operacja == "pobierzPlik alfabetyczne")
			przykladowy.pobierzPlik(true,alfabetyczne,odczyt);
		else if (operacja == "pobierzPlik alfanumeryczne")
			przykladowy.pobierzPlik(true,alfanumeryczne,odczyt);
		else if (operacja == "pobierzPlik bezBialychZnakow")
			przykladowy.pobierzPlik(true,bezBialychZnakow,odczyt);
		else if (operacja == "pobierzPlik bezNowychWierszy")
			przykladowy.pobierzPlik(true,bezNowychWierszy,odczyt);
		else if (operacja == "wypiszNaEkranie")
			przykladowy.wypiszNaEkranie(true);
		else if (operacja == "obliczDlugosc")
			cout << "Dlugosc powyzszego tekstu wynosi " << przykladowy.obliczDlugosc() << " znakow." << endl;
		else if (operacja == "kopiujTekst")
		{
			Tekst kolejny;
			przykladowy.kopiujTekst(kolejny);
			kolejny.wypiszNaEkranie(true);
			cout << "Dlugosc skopiowanego tekstu wynosi " << przykladowy.obliczDlugosc() << " znakow." << endl;
		}
        else if (operacja == "wypiszDoPliku")
			przykladowy.wypiszDoPliku(true,zapis);
        else if (operacja == "wyczysc")
			przykladowy.wyczysc();
		licznik++;
	}
	cout << "Wykonano w sumie " << licznik << "operacji" << endl;

	komendy.close();
	odczyt.close();
	zapis.close();
	return 0;
}

//==================================================
// Nazwa          : napisy.cpp
//==================================================

#include "napisy.h"

void Tekst::wyczysc() {
	znaki[0] = '\0';
	cout << "Zawartosc tekstu zostala wyczyszczona." << endl;
}

void Tekst::pobierzPlik(bool flaga, Rodzaj przyznany, ifstream& wejscie) {
	char litera;
	unsigned short licznik = 0;
	do {
		wejscie.get(litera);
		if (okreslFlage(przyznany, litera) && licznik < ROZMIAR) {
			znaki[licznik] = litera;
			licznik++;
		}
	} while (!wejscie.eof());
	znaki[licznik] = '\0';
}

void Tekst::wypiszNaEkranie(bool nowaLinia) {
	if (nowaLinia) {
		cout << "Tekst po konwersji:" << endl;
		cout << znaki << endl;
	}
}

void Tekst::wypiszDoPliku(bool nowaLinia, ofstream& wyjscie) {
	if (nowaLinia)
    {
        wyjscie << znaki;
        cout << "Zapisano zawartosc do wskazanego pliku." << endl;
    }
}

void Tekst::kopiujTekst(Tekst& fragment) {
	strcpy(fragment.znaki, znaki);
}

int Tekst::obliczDlugosc() {
	return strlen(znaki);
}

bool okreslFlage(Rodzaj Typ, char &litera) {
	switch (Typ) {
	case alfabetyczne:
		return isalpha(litera);
	case alfanumeryczne:
		return isalnum(litera);
	case bezBialychZnakow:
		return !isspace(litera);
	case bezNowychWierszy:
		return litera != '\n';
	}
	return 0;
}

void okreslOtwarcie(ifstream& uchwyt) {
	if (uchwyt.good())
		cout << "Poprawnie otwarto plik wejsciowy." << endl << endl;
	else {
		cout << "Nieprawidlowy stan strumienia danych." << endl;
		cout << "Zamkniecie aplikacji." << endl;
		exit (STATUS);
	}
}

void okreslOtwarcie(ofstream& uchwyt) {
	if (uchwyt.good())
		cout << "Poprawnie otwarto plik wyjsciowy." << endl << endl;
	else {
		cout << "Nieprawidlowy stan strumienia danych." << endl;
		cout << "Zamkniecie aplikacji." << endl;
		exit (STATUS);
	}
}

Rodzaj rzutujWyliczeniowo(string napis) {
	if (napis == "alfabetyczne")
		return alfabetyczne;
	else if (napis == "alfanumeryczne")
		return alfanumeryczne;
	else if (napis == "bezBialychZnakow")
		return bezBialychZnakow;
	else
		return bezNowychWierszy;
}
//==================================================
// Nazwa          : napisy.h
//==================================================

#ifndef NAPISY_H
#define NAPISY_H
#include <iostream>
#include <cstdio>
#include <cstring>
#include <fstream>
#include <cstdlib>

static const short ROZMIAR = 128;
static const unsigned short STATUS = USHRT_MAX;

using namespace std;

enum Rodzaj {
	alfabetyczne, alfanumeryczne, bezBialychZnakow, bezNowychWierszy
};

class Tekst {
private:
	char znaki[ROZMIAR];
public:
	void wyczysc();
	void pobierzPlik(bool flaga, Rodzaj przyznany, ifstream& wejscie);
	void wypiszNaEkranie(bool nowaLinia);
	void wypiszDoPliku(bool nowaLinia, ofstream& wyjscie);
	void kopiujTekst(Tekst& fragment);
	int obliczDlugosc();
};

bool okreslFlage(Rodzaj Typ, char &Litera);
void okreslOtwarcie(ifstream& uchwyt);
void okreslOtwarcie(ofstream& uchwyt);
Rodzaj rzutujWyliczeniowo(string napis);

#endif
pobierzPlik alfabetyczne
wypiszNaEkranie
obliczDlugosc
kopiujTekst
wypiszDoPliku
wyczysc
pobierzPlik alfanumeryczne
wypiszNaEkranie
obliczDlugosc
kopiujTekst
wypiszDoPliku
wyczysc
pobierzPlik bezBialychZnakow
wypiszNaEkranie
obliczDlugosc
kopiujTekst
wypiszDoPliku
wyczysc
pobierzPlik bezNowychWierszy
wypiszNaEkranie
obliczDlugosc
kopiujTekst
wypiszDoPliku
wyczysc
7E5L1 CHCE52 2N4LE5C 2R0DL0,
MUS152 15C D0 60RY, P0D PR4D.
PR2ED21ER47 51E, 52UK47, N1E U5TEPU7.

https://drive.google.com/folderview?id=0B7P1TugcU99rWWg5X2wtVEV0eFE&usp=sharing

1 odpowiedź

+1 głos
odpowiedź 30 sierpnia 2016 przez afferu Mądrala (5,220 p.)
wybrane 30 sierpnia 2016 przez plkpiotr
 
Najlepsza

Jak odczytujesz plik do samego końca, to żeby wrócić na początek musisz zresetować flagę eof

ifile.clear();
ifile.seekg(0, ios::beg);

 

komentarz 30 sierpnia 2016 przez plkpiotr Stary wyjadacz (12,420 p.)

Serdecznie dziękuję za pomoc, cały wieczór siedziałem nad tym zagadnieniem i nie potrafiłem rozwiązać tego problemu, zabrakło tylko wyczyszczenia flagi błędów, czyli plik.clear().

Podobne pytania

+1 głos
1 odpowiedź 179 wizyt
pytanie zadane 12 września 2015 w C i C++ przez k222 Nałogowiec (30,150 p.)
+1 głos
3 odpowiedzi 719 wizyt
0 głosów
1 odpowiedź 844 wizyt
pytanie zadane 18 lutego 2017 w Java przez plkpiotr Stary wyjadacz (12,420 p.)

92,451 zapytań

141,261 odpowiedzi

319,073 komentarzy

61,853 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!

...