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

Διάβασμα sting και integer από αρχείο κειμένου στην C++


choikono

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

γεια σας παιδία θα ήθελα να μου πει καποιοσ πως μπορώ να διαβασω ενα string απο ενα αρχειο κειμένου και στην συνέχεια να διαβασω και ενα int σε C++.Εχω προσπαθήσει με κάποιες εντολες αλλα η ανναγνωση του string συνεχιζεται μεχρι το τελος του αρχειου η' δεν διαχωρίζει το string απο το integer κλπ..Παρακάτω εχω ενα παραδειγμα για το τι ζητάω.

 

 

STACK_CREATE 1; // κατασκευή στοίβας με κωδικό 1

AVL_CREATE 1; // κατασκευή δένδρου AVL με κωδικό 1

STACK_PUSH 1, 10; // εισαγωγή του 10 στη στοίβα

AVL_INSERT 1, 100; // εισαγωγή του 100 στο δένδρο AVL

AVL_SEARCH 1, 100; // αναζήτηση του 100 στο δένδρο AVL

STACK_DESTROY 1; // καταστροφή της στοίβας 1

AVL_DETROY 1; // καταστροφή του δένδρου AVL 1

 

 

Δηλαδή θέλω πρωτα να διαβαζω το STACK_CREATE ,να κανω για παραδειγμα μια συγκριση ωστε να επαληθεύσω οτι ειναι αυτη η εντολη, και μετα να διαβασω το int .

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

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Δοκίμασε αυτό - βέβαια είναι γραμμένο σε απλή C, ελπίζω να μην σε πειράζει αυτό.

>
#include <stdio.h>

int main() {
char *szCmd=(char*)malloc(sizeof(char)*20);
int iCode,iCode2;
FILE *f=fopen("entoles.txt","r");
//Μπορείς να αλλάξεις το entoles.txt με το όνομα του αρχείου
//το οποίο θα διαβάζει το πρόγραμμα για τις εντολές
while (!feof(f)) {
	if (fscanf(f,"%s %d,%d",szCmd,&iCode,&iCode2)==3) //Το fscanf επιστρέφει τον αριθμό των στοιχείων
//που διαβάστηκαν σωστά, σ'αυτή την περίπτωση θα πρέπει να'ναι 3 αν οι παράμετροι είναι 2
	printf("Entoli: %s - Kwdikoi: %d %d\n",szCmd,iCode,iCode2);
	else printf("Entoli: %s - Kwdikos: %d\n",szCmd,iCode);
//Αν η εντολή έχει μόνο μια παράμετρο, το πρώτο fscanf δεν μπορεί να διαβάσει το ",%d", οπότε σταματάει εκεί
//Γι'αυτό διαβάζω την υπόλοιπη γραμμή σ'αυτό το σημείο
	fscanf(f,"%*[^\n]%*c");
//Σ'αυτό το σημείο μπορείς να επεξεργαστείς κάθε εντολή
//Η εντολή είναι αποθηκευμένη στο szCmd και οι παράμετροι στα iCode,iCode2
}
fclose(f);
free(szCmd);
getchar();
return 0;
}

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Το παρακάτω πρόγραμμα είναι γραμμένο κάπως γρήγορα και δεν σε καλύπτει εφόσον δεν κάνει parsing για εντολές που έχουν παραπάνω από ένα ορίσματα. Δουλεύει για απλά ορίσματα όπως πχ <ΕΝΤΟΛΗ> <ΑΡΙΘΜΟΣ>. Για να το κάνεις να δουλεύει για τα άλλα έχεις 2 επιλογές, είτε να ορίσεις ένα πίνακα από strings που να περιέχουν τις εντολές και να κοιτάς αν η εντολή που διάβασες υπάρχει εκεί οπότε check για τα υπόλοιπα ορίσματα, είτε manually να checkαρεις κάθε φορά αν υπάρχει πχ το ',' για να πάρεις το άλλο όρισμα. Το θέμα είναι πως το θέλεις εσύ να το κάνεις. Παραθέτω τον κώδικα:

 

>
//---------------------------------------------------------------------------

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

#define BUFSZ 512

using namespace std;

//---------------------------------------------------------------------------

class FileReader
{
public:
	FileReader(const int Sz);
	~FileReader();
	void ReadFromFile(const string& filename);
	void PrintContents() const;

private:
	int nSize;
	vector <int> nVector;
	vector <string> nStrings;
};

FileReader::FileReader(const int Sz)
{
nSize = Sz;
nVector.reserve(nSize);
nStrings.reserve(nSize);
}
FileReader::~FileReader()
{
nSize = 0;
nVector.erase(nVector.begin(), nVector.end());
nStrings.erase(nStrings.begin(), nStrings.end());
nVector.~vector<int>();
nStrings.~vector<string>();
}
void FileReader::ReadFromFile(const string& filename)
{
ifstream file(filename.c_str());
if(!file)
{
	cerr << "Cant open filename: " << filename << endl;
	return;
}
else
{
	/* Allocate an array of characters. */
	char *nArrayChar = new char[bUFSZ];
	if(!nArrayChar)
	{
		cerr << "Error in allocating array." << endl;
		file.close();
		return;
	}
	else
	{
		while(file.getline(nArrayChar, BUFSZ, '\n'))
		{
			int strInteger = 0;
			string LineStr = nArrayChar;
			string::size_type nPosition = LineStr.find(' ');
			if(nPosition == string::npos)
			{
				cerr << "Error File Record Format." << endl;
				file.close();
				break;
			}
			else
			{
				string strTemp(&LineStr[0], &LineStr[nPosition]);
				nStrings.push_back(strTemp);
				string strInt(&LineStr[++nPosition], LineStr.end());
				strInteger = atoi(strInt.c_str());
				nVector.push_back(strInteger);
			}
			memset(nArrayChar, 0 , BUFSZ);
			LineStr.clear();
		}
		file.close();
		delete[] nArrayChar;
	}
}
}
void FileReader::PrintContents() const
{
vector<string>::const_iterator nIterStr;
vector<int>::const_iterator nVecIter;
for(nIterStr = nStrings.begin(), nVecIter = nVector.begin(); nIterStr < nStrings.end() && nVecIter < nVector.end(); nIterStr++, nVecIter++)
	cout << *nIterStr << " " << *nVecIter << endl;
}
int main(int argc, char* argv[])
{
FileReader nReader(80);
nReader.ReadFromFile("file.txt");
nReader.PrintContents();
nReader.~FileReader();
cout << "Hit enter to continue..." << endl;
cin.get();
return 0;
}
//---------------------------------------------------------------------------

 

Εκτυπωμένα αποτελέσματα από αρχείο που ονομάζεται file.txt και βρίσκεται στο Debug φάκελο του CodeGear C++ Builder 2007:

 

STACK_CREATE 1

AVL_CREATE 1

STACK_PUSH 1

AVL_INSERT 1

AVL_SEARCH 1

STACK_DESTROY 1

AVL_DETROY 1

Hit enter to continue...

 

Στην ουσία επιστρέφεται οτι διαβάστηκε από το αρχείο μόνο που τις εντολές τις έχω σε ένα πινακα από strings και τους αριθμούς σε ένα πίνακα από ακεραίους.

 

Φιλικά,

Bokarinho...

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Δοκίμασε αυτό - βέβαια είναι γραμμένο σε απλή C, ελπίζω να μην σε πειράζει αυτό.

>
#include <stdio.h>

int main() {
char *szCmd=new char[20];
int iCode;
FILE *f=fopen("entoles.txt","r");
//Μπορείς να αλλάξεις το entoles.txt με το όνομα του αρχείου
//το οποίο θα διαβάζει το πρόγραμμα για τις εντολές
while (!feof(f)) {
	fscanf(f,"%s %d%*[^\n]%*c",szCmd,&iCode);
	printf("Entoli: %s - Kwdikos: %d\n",szCmd,iCode);
//Σ'αυτό το σημείο μπορείς να επεξεργαστείς κάθε εντολή
//Η εντολή είναι αποθηκευμένη στο szCmd και ο κωδικός στο iCode
}
fclose(f);
getchar();
return 0;
}

 

Αυτό δεν είναι C++, είναι C με μία ξέμπαρκη new από την C++, γενικά είναι λάθος να κάνουμε μίξη ρουτίνων από C σε C++ και vice verca... Κατά τα άλλα έξυπνη σύλληψη.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Ωραίος ο κώδικα του Bokarinho & Aesmade - μια πρόταση, αντί για δυο vector μπορεί να δηλωθεί ένα typedef (ή ακόμα καλύτερα και πιο C++ oriented, ένα class) που θα περιλαμβάνει την εντολή Cmd και το Count ως δυο members σε ένα vector<typedef>, μάλιστα σε περίπτωση άγνωστης εντολής (Cmd) διακόπτουμε το πρόγραμμα και ενημερώνουμε το χρήστη κτλ.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Αυτό δεν είναι C++, είναι C με μία ξέμπαρκη new από την C++, γενικά είναι λάθος να κάνουμε μίξη ρουτίνων από C σε C++ και vice verca... Κατά τα άλλα έξυπνη σύλληψη.

Α ναι sorry για το new, το'χω συνηθίσει και ξεχνάω πως είναι C++... Θα το διορθώσω.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

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

 

>
//---------------------------------------------------------------------------

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

#define BUFSZ 512

using namespace std;

//---------------------------------------------------------------------------

const char *SpecialCommands[] = { "STACK_PUSH", "AVL_INSERT", "AVL_SEARCH"};

/* Search if there is a command in the array of special commands. */
bool SPCommandExists(const char *Cmd)
{
int i;
for(i = 0; SpecialCommands[i] != NULL; i++)
{
   if(!strcmp(SpecialCommands[i], Cmd))
	return true;
}
return false;
}

class FileReader
{
public:
	FileReader(const int Sz);
	~FileReader();
	void ReadFromFile(const string& filename);
	void PrintContents() const;

private:
	int nSize;
	vector <int> nVector;
	vector <int> nSPVector;
	vector <string> nStrings;
};

FileReader::FileReader(const int Sz)
{
nSize = Sz;
nVector.reserve(nSize);
nSPVector.reserve(nSize);
nStrings.reserve(nSize);
}
FileReader::~FileReader()
{
nSize = 0;
nVector.erase(nVector.begin(), nVector.end());
nSPVector.erase(nSPVector.begin(), nSPVector.end());
nStrings.erase(nStrings.begin(), nStrings.end());
nVector.~vector<int>();
nSPVector.~vector<int>();
nStrings.~vector<string>();
}
void FileReader::ReadFromFile(const string& filename)
{
ifstream file(filename.c_str());
if(!file)
{
	cerr << "Cant open filename: " << filename << endl;
	return;
}
else
{
	/* Allocate an array of characters. */
	char *nArrayChar = new char[bUFSZ];
	if(!nArrayChar)
	{
		cerr << "Error in allocating array." << endl;
		file.close();
		return;
	}
	else
	{
		while(file.getline(nArrayChar, BUFSZ, '\n'))
		{
			int strInteger = 0, strInteger1 = 0;
			string LineStr = nArrayChar;
			string::size_type nPosition = LineStr.find(' ');
			if(nPosition == string::npos)
			{
				cerr << "Error File Record Format, missing ' '" << endl;
				file.close();
				break;
			}
			else
			{
				string strTemp(&LineStr[0], &LineStr[nPosition]);
				nStrings.push_back(strTemp);
				/* If we encounter a special command that need second argument parse it. */
				if(SPCommandExists(strTemp.c_str()))
				{
					string::size_type nposComma = LineStr.find(',');
					if(nposComma == string::npos)
					{
						cerr << "Error File Record Format, missing ','" << endl;
						file.close();
						break;
					}
					else
					{
						string strInt1(&LineStr[++nPosition], &LineStr[nposComma]);
						string strInt2(&LineStr[++nposComma], LineStr.end());
						strInteger = atoi(strInt1.c_str());
						strInteger1 = atoi(strInt2.c_str());
						nVector.push_back(strInteger);
						nSPVector.push_back(strInteger1);
					}
				}
				else
				{
					string strInt(&LineStr[++nPosition], LineStr.end());
					strInteger = atoi(strInt.c_str());
					nVector.push_back(strInteger);
					nSPVector.push_back(0);
				}
			}
			memset(nArrayChar, 0 , BUFSZ);
			LineStr.clear();
		}
		file.close();
		delete[] nArrayChar;
	}
}
}
void FileReader::PrintContents() const
{
vector<string>::const_iterator nIterStr;
vector<int>::const_iterator nVecIter, nSPVecIter;
for(nIterStr = nStrings.begin(), nVecIter = nVector.begin(), nSPVecIter = nSPVector.begin(); nIterStr < nStrings.end() && nVecIter < nVector.end() && nSPVecIter < nSPVector.end(); nIterStr++, nVecIter++, nSPVecIter++)
{
	cout << *nIterStr << " " << *nVecIter << " ";
	if(*nSPVecIter)
		cout << *nSPVecIter;
	cout << endl;
}
}

int main(int argc, char* argv[])
{
FileReader nReader(80);
nReader.ReadFromFile("file.txt");
nReader.PrintContents();
nReader.~FileReader();
cout << "Hit enter to continue..." << endl;
cin.get();
return 0;
}
//---------------------------------------------------------------------------

 

Εκτυπωμένα αποτελέσματα από το αρχείο κειμένου file.txt που περιέχει τα:

STACK_CREATE 1

AVL_CREATE 1

STACK_PUSH 1, 10

AVL_INSERT 1, 100

AVL_SEARCH 1, 10

STACK_DESTROY 1

AVL_DETROY 1

 

είναι:

 

STACK_CREATE 1

AVL_CREATE 1

STACK_PUSH 1 10

AVL_INSERT 1 100

AVL_SEARCH 1 10

STACK_DESTROY 1

AVL_DETROY 1

Hit enter to continue...

 

Καλή συνέχεια...

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

  • 3 χρόνια αργότερα...

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

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

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