[C++] Odczytywanie z pliku, problem


(Ovitz Pl) #1

Witam, otóż mam taki problem: Zapisuje dane do pliku txt, następnie chce je odczytać:

Program wygląda tak:

#include "stdafx.h"

#include "conio.h"

#include 

#include 

#include 


using namespace std;


struct dane 

{

	char nazwa [51];

	char gatunek [51];

	int rok;

};		

int _tmain(int argc, _TCHAR* argv[])

{


	dane d;

		cout<<"Podaj nazwe gryy: "; cin.getline(d.nazwa, 50);

		cout<<"\nPodaj gatunek gry: "; cin.getline(d.gatunek, 50);

		cout<<"\nPodaj rok wydania gry: "; cin>>d.rok;

		cout<
		cout<

		fstream plik;

		plik.open ("dane.txt", ios::in | ios::out);

		plik<<"N: "<
		//plik>>d.nazwa>>d.gatunek>>d.rok;

		plik.close ();

		cout<
		_getch();

	return 0;

}

Plik wygląda tak:

N:Age of Empires G:Strategia R:1999999

Jak odczytać plik aby odzielnie wpisać do stuktur Age of Empires, Strategia, 1999?

Ps. I dlaczego jak wpisuje rok 1999 to w pliku mi się zapisuje 1999999?


([alex]) #2

Takiego pliku nie da się poprawnie odczytać, ponieważ jeżeli nazwa gry będzie zawierała dwa znaki "G:" to już nie będziesz wiedział gdzie zaczyna się kategoria.

Jeżeli zapisywać:

plik<<d.nazwa<<endl<<d.gatunek<<endl<<d.rok<<endl; [/code]

To odczytuje się to:

[code=php]plik.getline(d.nazwa,50);
plik.getline(d.gatunek,50);
plikd.rok; 

Ale jednak radze zapisywać w postaci binarnej.

W pliku są resztki z poprzedniego zapisu.

Spróbuj zapisać tam

nazwa: Baaaaaaaaaaaaardzo dluuuuuuuuuuuuga naaaaaaaaaazwa

gatunek: Dluuuuuuuuuuga naaaaaaaaaaaazwa gaaaaaaaaaaaatunku

rok: 9999

a potem zapisać:

nazwa: Age of Empires

gatunek: Strategia

rok: 1999

i zobacz co będzie w pliku :smiley:


(Ovitz Pl) #3


([alex]) #4

Zapis dwóch rekordów:

plik.open ("dane.txt", ios::out);plikd.nazwa'|'d.gatunek'|'d.rokendl;strcpy(d.nazwa,"druga"); strcpy(d.gatunek,"drugi"); d.rok=1000;plikd.nazwa'|'d.gatunek'|'d.rokendl;plik.close(); [/code]



Odczyt tylu ile jest:
[code=php]plik.open ("dane.txt", ios::in);plik.eof())

(Ovitz Pl) #5

Czym się różni zapisa binarny od tego? Poza oczywiscie cyferkami? Co można za jego sposobem osiagnać?

I tak dla estetyki, jak bym chciał najpierw napisać "Nazwa Gry:" a wczytać ją z pliku to da się to jakoś zrobić plik.getline czy musze coutem to napisac zanim wczytam?


([alex]) #6
  1. [*:26jvumy3]Zapis binarny jest nieco szybszy chociażby z powodu mniejszego rozmiaru*, łatwo jest wykluczyć ingerencje użyszkodnika w treść pliku.[*:26jvumy3]plik.getline - pobiera wiersz z pliku, jeżeli w pliku nie zapisano "Nazwa Gry:" to za pomocą getline tego nie wczytasz.

*Tak jest przeważnie, ale zawsze można wymyślić przykład dla którego zapis binarny będzie dłuższy niż tekstowy.


(Ovitz Pl) #7

Dzięki za pomoc, jeszcze napewno dziś zgłosze się o pomoc, a póki co możesz mi wyjaśnić od czego ta linia jest?

while(!plik.eof() && plik.get()!='\') ;

(Kalin 93) #8

Do 'przesówania' się do pliku :wink:


(Ovitz Pl) #9

Kolejny problem:

Funkcaj odczyt, nie odczytuje z pliku:

A fukncja zapis po właczenie od razu przeskakuje do do Podaj rodzaj, a wczesniej powinnenem podać nazwe, ktoś wie dlaczego?


([alex]) #10

Oczywiście, bo plik zaczynasz z pustego wiersza, a przy odczycie pusty wiersz czytasz jako nazwę, potem nazwę czytasz jako gatunek, potem próbujesz czytać gatunek jako rok a to już programowi się nie udaje.

Tak a propos, próbowałeś w tym twoim menu głównym wpisać literkę zamiast liczby?

Trochę to uporządkowałem, ale nadał to jest brzydkie rozwiązanie

#include

(Ovitz Pl) #11

Wszstko gra tylko z jednym jest problem przy ocdczytywaniu z pliku, pierwszy wiersz dobrze odczytuje, ale kolejne:

Nazwa: 1 Rodzaj: 1 Rok: 1999

Nazwa:

2 Rodzaj: 2 Rok: 1999

Nazwa:

3 Rodziaj: 3 Rok: 1999

Pustą linie pobiera.

A cin.ignore/clean może ktoś objaśnić jak ona działa?


([alex]) #12

Zobacz co masz w pliku, przed chwilą skompilowałem i odpaliłem to co podałem wczoraj, nie ma problemu który opisujesz.

ios::clear(); - Czyści flagi ustawione w cin, na przykład flagę ios:bad_bit; ta flaga ustawia się kiedy podczas próby wczytania liczby kiedy na wejściu są litery. Jeżeli flaga ios:bad_bit ustawiona to nie działa żadna instrukcja czytająca czy też wpisująca z/do strumienia.

http://www.cplusplus.com/reference/iost ... clear.html

istream::ignore(Max,EndChar); - Wyrzuć z wejścia (ignoruj) nie więcej niż Max znaków do najbliższego znaku EndChar.

http://www.cplusplus.com/reference/iost ... gnore.html


(Ovitz Pl) #13

W pliku wszystko dobrze: A dobrze Ci pokazuje po kompilacja bo jest mały błąd:

void odczyt()

{

dane d;

fstream plik;

plik.open("dane.txt",ios::in);

while(true)

{

plik.getline(d.nazwa,51,'.'); // użytkownik mógł ngerować w plik ręcznie

plik.getline(d.gatunek,51,'.'); // nadał trzeba kontrolować rozmiar

plik>>d.rok;

if(!plik) break; // jeżeli kolejny odczyt się nie udał

cout<<"Nazwa: "<

}

plik.close();

cout<

}

Teraz spróbój.


([alex]) #14

Aha, już widzę:

po plik>>d.rok; daj

plik.ignore(INT_MAX,'\n');