Προς το περιεχόμενο

δημιουργια - εγγραφη - αναγνωση .dat αρχειων σε C++


tolis86

Προτεινόμενες αναρτήσεις

Δημοσ.

την βοηθεια σας!!! το μονο που ξερω ειναι οτι πρεπει να συμπεριλαβω το fstream. ποιες ειναι και πως λειτουργουν οι εντολες? αυτο που προς το παρον σκευτομαι να κανω ειναι να γραφω σε ενα .dat αρχειο εναν 4διαστατο πινακα. μετα να ανοιγω το .δατ και να διαβαζω τον πινακα που ειχα γραψει και στειχεια αυτου τα θελω για να κανω καποιες συγκρισεις, ταξινομισεις κλπ. αυτο που δε ξερω πως να κανω ειναι το πως θα γραψω τον πινακα. ο πινακας αυτος να πω πως τον εχω μεσα σε μια struct αυτο βεβαια μπορει να αλαξει και να μη φτιαξω καθολου την στρακτ αν ειναι πιο δυσκολο-ακατορθωτο. ΕΥΧΑΡΙΣΤΩ!

Δημοσ.

Γεια να σε βοηθήσω θα σου δώσω λίγο κώδικα. Με ofstream file ορίζεις ένα αρχείο για να γράψεις σε αυτό ενώ αντίθετα με ifstream file ορίζεις ένα αρχείο για να διαβάσεις από, ενώ αν θυμάμαι καλά με fstream file μπορείς να τα κάνεις όλα και να διαβάσεις και να γράψεις στο αρχείο που ορίζεις.

 

Ετσι.

 

ofstream outfile;

outfile.open("to_onoma_tou_arxeiou.dat");

 

or

 

ofstream outfile;

char filename[100];

cout << "Δώσε μου το όνομα του αρχείου στο οποίο θέλεις να γράψεις";

cin >> filename;

outfile.open(filename);

 

Τώρα για να διαβάσεις από αρχείο ακολουθείς την ίδια διαδικασία μόνο που αντί για ofstream -> ifstream.

Πολύ χρήσιμη συνάρτηση για τα αρχεία στην C++ είναι η εξής:

example.

 

ifstream afile;

afile.open("numbers.dat");

if(afile.fail() == 1)

{

cout << "Some error has been made and the file hasnt been opened or god knows what";

return -1;

}

Γεια να κλείσεις ένα αρχείο ανάλογα με afile.close();

Τώρα τα σημαντικότερα,για να γράψεις λοιπόν μέσα σε ένα αρχείο κάνεις το εξής.

ofstream afile;

string data;

int number;

afile.open("the_file.dat");

if(afile == NULL)

{

cout << "Error";

return -1;

}

//get some data

getline(cin,data);

//write to file

afile << data << endl;

cout << "Dwse moy ena arithmo:";

cin >> number;

//write the number to file

afile >> number >> endl;

//close file

afile.close();

 

Ανάλογα μπορείς να διαβάσεις από το αρχείο τα δεδομένα που έχεις γράψει ως εξής:

afile.open("the_file.dat");

getline(afile,data);

while(!afile.fail())

{

//if you want to see what is read cout << data << endl;

getline(afile,data);

}

afile.close();

 

Ενα άθλιο tutorial για C++..........

 

 

Αυτά από εμένα ελπίζω να σε βοήθησα λίγο...:neutral:

Δημοσ.

με αυτο: afile << data << endl; "λεμε" στον κομπαιλερ οτι θα γραφτουν δεδομενα?

μπορω να γραψω: afile>>name_of_struct.array[j][x][z]>>endl; ????

(οπου ο πινακας ειναι μεσα στην στρακτ)

για να διαβασω ολο το αρχειο τι γραφω? αν γινεται βεβαια. και τα διαβασμενα υπο ποιας μορφης και που αποθηκευονται? απλα προβαλονται?

μπορω να γραψω αν πχ θελω να διαβασω μια σειρα και να το αποθηκευσω το εξης: getline(afile,data)=char; ?????

 

κατα τα αλλα βοηθησες πολυ ευχαριστω! αυτα ακομα να μου διασαφηνισεις και νομιζω πως θα τα καταφερω!

Δημοσ.

Έχεις ένα πίνακα μέσα σε μία struct. Γιατί δεν γράφεις όλη την δομή μέσα στο αρχείο;Τέλος πάντων δεν γνωρίζω ακριβώς τι θέλεις να κάνεις αλλά για να γράψεις ένα πίνακα σε ένα αρχείο το ανοίγεις για γράψιμο με την παραπάνω διαδικασία και προφανώς μέσα σε 4 loop κάνεις την δουλειά. Δηλαδή.

int i,j,x,z;

for(i=0;i<n;i++)

{

for(j=0;j<m;j++)

{

for(x=0;x<k;x++)

{

for(j=0;j<l;j++)

{

afile << domi.array[j][x][z] << endl;

}

}

}

}

Εννοείται οτι θα πρέπει να έχεις δώσει τις παραμέτρους n,m,k,l για τον πίνακα σου. Αν και δεν γνωρίζω πολύ καλά C++ πιστεύω ότι αυτό θα δουλέψει γιατί κάθε φορά το domi.array[j][x][z] αναπαριστά ένα αριθμό. Εννοείται ότι τον πίνακα τον έχεις γεμίσει κάπου πριν απλά δεν γνωρίζω τι γίνεται με τόσο μεγάλους πίνακες δεν το έχω δοκιμάσει. Με αυτόν τον τρόπο γράφεις δεδομένα στο αρχείο. Τώρα για να τα διαβάσεις από το αρχείο κάνε μια do - while με την συνθήκη να είναι η εξής:

 

string data;

do

{

getline(afile,data); //diabase mia grammi apo to arxeio afile kai balthn sto data

//twra exeis mesa sto data tin prwth grammi toy arxeioy

//kane kati me to data twra poy to exeis

}while(!afile.fail());

 

Πάντως εμένα αυτό μου έτρεξε για δοκίμασε το,δημιούργησε όντως ένα αρχείο με αριθμούς μέσα.Τώρα για το διάβασμα δοκίμασε το από πάνω και να φροντίζεις κάθε φορά την κάθε γραμμή που διαβάζεις από το αρχείο να την γράφεις στον πίνακα.Στην περίπτωση μας η κάθε γραμμή είναι αριθμός.Τώρα άν θες να γράψεις ένα string,τότε εκεί που διαβάζεις την γραμμή και την αποθηκεύεις κάπου μετά βλέπεις την μορφή του και το περνάς στην δομή σου.Αν δεν καταλαβαίνεις κάτι μπορώ να σου δείξω έυκολά σε C.

 

#include <cstdlib>

#include <iostream>

#include <fstream>

 

using namespace std;

 

int main(int argc, char *argv[])

{

int i,j,x,z;

int array[5][6][8][10];

ofstream afile;

afile.open("test.txt");

if(!afile)

{

cout << "Error opening file for writing to." << endl;

exit(1);

}

for(i=0;i<5;i++)

{

for(j=0;j<6;j++)

{

for(x=0;x<8;x++)

{

for(z=0;z<10;z++)

{

array[j][x][z] = z*(x+j-i);

afile << array[j][x][z] << endl;

}

}

}

}

afile.close();

system("PAUSE");

return EXIT_SUCCESS;

}

Δημοσ.

μαληστα.... βασικα το μονο πραμα που ειχε η δομη ηταν ο πινακας οποτε και τελικα την κατηργησα...τωρα εχω απλα εναν πινακα Α[][][][].αυτος εχει τιμες μεσα(αριθμους). αυτες τις τιμες θελω να τις περασω στο .δατ και μετα θελω να μπορω να ανοιγω το .δατ, να διαβαζω τις τιμες και να τις αποθηκευσω μια μια σε εναν αντιστοιχο πινακα(ιδιων διαστασεων δλδ) και να μπουν στις ιδιες θεσεις ακριβως με τον πρωτο πινακα. με βοηθησες πολυ. νομιζω πως θα τα καταφερω αλλα αν μπορεις και συγνωμη αν ζηταω πολλα αλλα για να μη το κανω λαθος καπου και ποσταρω να μου το βρει καποιος μπορεις να γραψεις το κωδικα? παιδευομαι τοσες μερες μαυτο το πραμα...αρχαριος πολυ βλεπεις. ειμαι καπου στη μεση του προγραμματος που θελω να φτιαξω και χωρις αυτο το .δατ δε μπορω να προχωρισω....

Δημοσ.

Δεν καταλαβαίνω ένα πράγμα,γιατί ενώ έχεις ένα πίνακα και θέλεις να βάλεις τις τιμές σε έναν άλλον και να είναι ίδιες και στις ίδιες θέσεις του άλλου γιατί να χρησιμοποιήσεις το αρχείο στην μέση. Σου αρκεί μία ισότητα μέσα στα 4 loop που σου έγραψα. Σε αυτά που μου ζητάς σου έχω δώσει απάντηση,ο κώδικας από πάνω γράφει στο αρχείο (άλλαξε το σε .dat) κάποιους αριθμούς, αν θες τυχαίους βάλε rand() που παράγει τυχαίους αριθμούς. Όσον αφορά το διάβασμα είναι ακριβώς το ίδιο το μόνο που αλλάζει είναι το << σε >>.

Τώρα αν επιμένεις να το γράψω και σε κώδικα ΟΚ απλά δεν το θεωρώ απαραίτητο όταν τα έχεις όλα μπροστά σου.

 

Από C.

 

Ισχύει a = b.

Αν θες να αντιγράψεις δομές όμως τότε δεν ισχύει η ισότητα αλλά:

memcpy(&a,&b,sizeof(struct domi));

 

δεδομένου ότι έχεις ορίσει struct domi *a,*b;

Δημοσ.

Αν και δεν μπορώ να πω πως πολύ χρησιμοποιώ την C++ STL για την ιστορία θα ήθελα να αναφέρω ότι..

 

Μπορείς επίσης να χρησιμοποιήσεις τις ρουτίνες .write και .read των istream και ostream (ή fstream συνολικά) ώστε να αποθηκεύσεις κατευθείαν τον πίνακα σε δυαδική μορφή (binary).

 

Η ρουτίνα _SaveDAT δημιουργεί ένα αρχείο εξόδου (strFilename) στο οποίο γράφει τον int* πίνακα ptrArray μεγέθους stArraySize bytes με την βοήθεια της ρουτίνας write. Αν πρόκειται για πετυχημένη εγγραφή τότε η κλήση της ρουτίνας .bad() επιστρέφει μηδέν διαφορετικά ένα.

 

Η ρουτίνα _LoadDAT διαβάζει από το αρχείο εισόδου (strFilename) τον αποθηκευμένο με την _SaveDAT int* πίνακα μεταφέροντας τον στο πίνακα ptrArray μεγέθους stArraySize bytes με την βοήθεια της ρουτίνας read. Αν πρόκειται για πετυχημένη ανάγνωση τότε η κλήση της ρουτίνας .bad() επιστρέφει μηδέν διαφορετικά ένα.

 

Ο παρακάτω κώδικας είναι γραμμένος σε CodeGear Turbo C++ Explorer και επιδεικνύει τα παραπάνω - επειδή όπως προανέφερα δεν ασχολούμαι ιδιαίτερα με την STL θεωρώ δεδομένο ότι μπορεί να γραφθεί καλύτερα ενώ δεν αποκλείω την ύπαρξη bugs.

 

>
//---------------------------------------------------------------------------
#include <iostream>
#include <fstream>
//#pragma hdrstop

//---------------------------------------------------------------------------
using namespace std;
//---------------------------------------------------------------------------
int	Test[10][10][10][10];

int	_SaveDAT(string strFilename,void*,size_t);
int _LoadDAT(string strFilename,void*,size_t);

//#pragma argsused
int main(int argc, char* argv[])
{
   cout << "Generating original table:" << endl;
memset(&Test,0,sizeof(Test));
for(int nIdx=0;nIdx<10;nIdx++)
 for(int nIdxII=0;nIdxII<10;nIdxII++)
  for(int nIdxIII=0;nIdxIII<10;nIdxIII++)
   for(int nIdxIV=0;nIdxIV<10;nIdxIV++)
	 {
		Test[nIdx][nIdxII][nIdxIII][nIdxIV] = nIdx;
		cout << "["<<nIdx<<"]"<<"["<<nIdxII<<"]"<<"["<<nIdxIII<<"]"<<"["<<nIdxIV<<"]"<<"="<<Test[nIdx][nIdxII][nIdxIII][nIdxIV]<<endl;
	 }

if(!_SaveDAT("TEST.BIN",&Test,sizeof(Test)))
 cout << "Error during binary file write!" << endl;
else
 {
	memset(&Test,0,sizeof(Test));	// ..to prove binary read working right

	if(!_LoadDAT("TEST.BIN",&Test,sizeof(Test)))
	 cout << "Error during binary file read!" << endl;
	else
	 {
		cout << "Dumping saved table:" << endl << "Hit Enter to begin..";
		cin.get();
		for(int nIdx=0;nIdx<10;nIdx++)
		  for(int nIdxII=0;nIdxII<10;nIdxII++)
		   for(int nIdxIII=0;nIdxIII<10;nIdxIII++)
			for(int nIdxIV=0;nIdxIV<10;nIdxIV++)
			 {
				Test[nIdx][nIdxII][nIdxIII][nIdxIV] = nIdx;
				cout << "["<<nIdx<<"]"<<"["<<nIdxII<<"]"<<"["<<nIdxIII<<"]"<<"["<<nIdxIV<<"]"<<"="<<Test[nIdx][nIdxII][nIdxIII][nIdxIV]<<endl;
			 }
	 }
 }

cout << endl << "Hit Enter to quit..";
cin.get();
return 0;
}
//---------------------------------------------------------------------------
int	_SaveDAT(string strFilename,void* ptrArray,size_t stArraySize)
{
int		 nSuccess	= 0;
fstream  FileStream;

FileStream.open(strFilename.c_str(),ios::out|ios::binary);
if(FileStream.is_open())
 {
	FileStream.write((char*)ptrArray,stArraySize);
	nSuccess = !FileStream.bad();	// .bad() = 0 then write was ok (!0->1)
	FileStream.close();
 }

return nSuccess;
}

int _LoadDAT(string strFilename,void* ptrArray,size_t stArraySize)
{
int		nSuccess = 0;
fstream FileStream;

FileStream.open(strFilename.c_str(),ios::in|ios::binary);
if(FileStream.is_open())
 {
	FileStream.read((char*)ptrArray,stArraySize);
	nSuccess = !FileStream.bad();	// .bad() = 0 then read was ok (!0->1)
	FileStream.close();
 }

return nSuccess;
}

 

Υ.Γ.

Διαβάζω και γράφω το ptrArray ως void* ώστε να διευκολύνω την διαχείριση του πολυδιάστατου (4D) πίνακα (int****) και συνάμα καθιστώντας τις ρουτίνες πιο εύκολα αδιάφορες ως προς την μορφή των δεδομένων που διαχειρίζονται (τα πάντα ως απλά bytes) -τώρα στον κόσμο της C++ αυτό είναι και δεν είναι ανεκτό..

Αρχειοθετημένο

Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.

  • Δημιουργία νέου...