Czytanie z pliku tekstowego

0

Hejo. Na wstepie chcialbym zaznaczyc ze JESZCZE nie znam klas i nawet nie biore pod uwage rozwiazan korzystajacych w duzej mierze z klas. (ta wiem ze c++ to same klasy). Znam troche C i zaczalem czytac ksiaże o c++, rozwiazuje zadania z tej ksiazki i staram sie wykorzystywać wiedzę uzyskana z tej ksiazki. Jak na razie mam podejscie "strukturalne" do c++ i probuje pisac programy nie uzywajac klas. oto tresc zadania: "wczytywac z pliku txt plik w postaci:

liczba_X
tekst moze byc tu duzo wyrazow [nazwisko]
liczba_i [liczba typu double]
...

przy czym liczba_X okresla ile jest par [nazwisko] + [double]. umieszczam swoj kod:

#include <iostream>
#include <fstream>    
#include <string>
using namespace std;
struct struktura {
	string nazwisko;
	double kwota;
};
int main()
{
	string nazwa_pliku = "Dane.txt";
	int rozmiar_tablicy = 0;
	ifstream inFile;
	inFile.open(nazwa_pliku);
	if (!inFile.is_open())
	{
		cout << "nie ma pliku\n";
		exit(EXIT_FAILURE);
	}
	inFile >> rozmiar_tablicy;
	double *tablica_double = new double[rozmiar_tablicy];
	string *tablica_string = new string[rozmiar_tablicy];
	int i = 0;
	while (inFile.good())
	{
		getline(inFile, tablica_string[i]);
		inFile >> tablica_double[i];
		i++;
	}
	if (inFile.eof())
		cout << "Koniec pliku.\n";
	else if (inFile.fail())
		cout << "Wczytywanie danych przerwane - błąd.\n";
	else
		cout << "Wczytywanie danych przerwane, przyczyna nieznana.\n";
	for (int j = 0; j < rozmiar_tablicy; j++)
		cout << tablica_string[j] << " <-> " << tablica_double[j] << endl;
	system("pause");
	return 0;
}

chce najpierw wczytac pierwsza liczbe z pliku i dzieki niej zalokowac pamiec na tablice. w C uzywało sie wskaznikow typu FILE. gdyby to bylo C to po wczytaniu liczby_X wskaznik bylby za nia i mozna byłoby wczytywać juz pary. niestety moj kod nie działa i prosiłym o pomoc. dzieki

1

while (inFile.good()) - Ta linia, wcale nie robi tego, co Ty myślisz że robi.
Zamień ją na while(!inFile.eof())
Masz przykład, lepiej używaj (już od początku) wektorów zamiast gołych wskaźników, będzie łatwiej :- )

 
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;

int main()
{
	fstream f("plik.txt");
	
	int numberOfEntries;
	f >> numberOfEntries;

	std::vector<std::string> names(numberOfEntries);
	std::vector<float>       values(numberOfEntries);

	int i = 0;
	
	while(!f.eof())
	{
		f >> names[i];
		f >> values[i];
		i++;
	}
	
	for(int i=0;i<numberOfEntries;++i)
		std::cout << names[i] << " " << values[i] << std::endl;
	
}

2

No ale @Craith czego nie rozumiesz z kodu, który Ci przysłałem?

string rozmiar = "";
getline(inFile, rozmiar);
 
string linijka = "";
int separator = 0;
 
nazwa *tablica = new nazwa[stoi(rozmiar)];
for (int i = 0; i < stoi(rozmiar); i++)
{
	getline(inFile, linijka);
	separator = linijka.find_last_of(" ");
	if (separator != string::npos){
		tablica[i].nazwisko = linijka.substr(0, separator);
		tablica[i].kwota = stod(linijka.substr(separator));
	}
	else break;
}

Ten kod jest odporny na ilość spacji, bo znajduje tylko ostatnią spację, która służy jako separator. To jest przecież przeróbka Twojego kodu.

0

tak wiem dziekuje. ale napisalem:

JESZCZE nie znam klas i nawet nie biore pod uwage rozwiazan korzystajacych w duzej mierze z klas

wiem ze dla was to 1, 2, 3 i program piszecie w glowie ale dla mnie jest to neizrozumiale. wyobraz sobie ze uczysz sie c++, znasz c i probujesz sie poruszac w tym co wiesz. nagle ktos ci wysyla taki kod i robisz wielkie :O

edit:
mozna robic vector struktur?a i czy z vectorami nalezy postepowac tak jak ze wszystkimi tablicami mallocowanymi w C? czyli jesli nie korzysta sie z nich to nalezy je zwalniac? czy z klasa array tez tak mozna postepowac?

1

Można, tak jak wektor klas, ale lepiej jest zrobić wektor wskaźników na klasy/struktury i do tego wektora przekazywać referencje do obiektów.

BTW: np. używanie FILE z C w C++ to nie jest prawidłowe podejście (tak, wiem, że nie używasz). Nie wiem szczerze mówiąc jak chcesz obsłużyć taki odczyt. Wyraźnie mi napisałeś na priv, że chcesz używać stingów zamiast char* więc w czym problem, że użyjesz getline?

Jak chcesz to zrobić w ogóle? Tak, żeby Cię to satysfakcjonowało. Po prostu nie wiem co Ci się nie podoba, w naszym podejściu? :) Bo w Proksimowym to jeszcze rozumiem, że kontenery etc. ale w moim to już tradycja takiego odczytu jest :)

0

zaskocze Was ale ten kod nie dziala:

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

using namespace std;
int main()
{
	fstream f("Dane.txt");

	int numberOfEntries;
	f >> numberOfEntries;

	vector<string> names(numberOfEntries);
	vector<double> values(numberOfEntries);

	int i = 0;

	while (!f.eof())
	{
		//f >> names[i];
		getline(f, names[i]);
		f >> values[i];
		cout << names[i] << " " << values[i] << endl;
		i++;
	}

	for (int i = 0; i<numberOfEntries; ++i)
		cout << names[i] << " " << values[i] << endl;

}

moja wizja rozwiazania problemu wyglada tak:
wczytuje pierwsza liczbe, nastepnie tworzy cos gdzie mozna przyszle dane zapisac. i w petli wczytywac caly wiersz [nastepna linijka] i liczbe z nastepnego wiersza.

0

Nie działa bo plik Proksimy ma inny format danych. @Proxima treści nie zrozumiałeś hehe.

1

Dobra, o to Ci pewnie chodzi:

Plik ma postać:

2
Waclaw Igrekowski
14.99
Tadeusz Iksinski
15.42

Natomiast kod na szybko jest taki:

#include <iostream>
#include <fstream>    
#include <string>
using namespace std;

struct Nazwa {
	string nazwisko;
	double kwota;
};

int main()
{
	fstream plik("bazaDanych.txt");
	if (plik.is_open()){
		string linijka = "";
		getline(plik, linijka);

		int rozmiar = stoi(linijka);
		Nazwa *tablica = new Nazwa[rozmiar];

		int numerLinijki = 0;
		int licznikTablicy = 0;
		while (getline(plik, linijka)){
			if (numerLinijki % 2) tablica[licznikTablicy].kwota = stod(linijka);
			else tablica[licznikTablicy].nazwisko = linijka;
			numerLinijki++;
			licznikTablicy++;
			licznikTablicy = numerLinijki - licznikTablicy;
		}

		for (int i = 0; i < rozmiar; i++)
			cout << tablica[i].nazwisko << " " << tablica[i].kwota << endl;

		plik.close();
		delete[] tablica;
	}
	else cout << "Blad odczytu!" << endl;
	system("pause");
	return 0;
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1