choikono Δημοσ. 6 Φεβρουαρίου 2008 Δημοσ. 6 Φεβρουαρίου 2008 γεια σας παιδία θα ήθελα να μου πει καποιοσ πως μπορώ να διαβασω ενα 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 . Αν εχει κανενας καμια ιδέα υλοποιησης θα του ήμουν ευγνώμων.
Aesmade Δημοσ. 7 Φεβρουαρίου 2008 Δημοσ. 7 Φεβρουαρίου 2008 Δοκίμασε αυτό - βέβαια είναι γραμμένο σε απλή 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; }
bokarinho Δημοσ. 7 Φεβρουαρίου 2008 Δημοσ. 7 Φεβρουαρίου 2008 Το παρακάτω πρόγραμμα είναι γραμμένο κάπως γρήγορα και δεν σε καλύπτει εφόσον δεν κάνει 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...
bokarinho Δημοσ. 7 Φεβρουαρίου 2008 Δημοσ. 7 Φεβρουαρίου 2008 Δοκίμασε αυτό - βέβαια είναι γραμμένο σε απλή 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... Κατά τα άλλα έξυπνη σύλληψη.
Directx Δημοσ. 7 Φεβρουαρίου 2008 Δημοσ. 7 Φεβρουαρίου 2008 Ωραίος ο κώδικα του Bokarinho & Aesmade - μια πρόταση, αντί για δυο vector μπορεί να δηλωθεί ένα typedef (ή ακόμα καλύτερα και πιο C++ oriented, ένα class) που θα περιλαμβάνει την εντολή Cmd και το Count ως δυο members σε ένα vector<typedef>, μάλιστα σε περίπτωση άγνωστης εντολής (Cmd) διακόπτουμε το πρόγραμμα και ενημερώνουμε το χρήστη κτλ.
choikono Δημοσ. 7 Φεβρουαρίου 2008 Μέλος Δημοσ. 7 Φεβρουαρίου 2008 euxaristw polu paidia 8a to dokimasw kai 8a sas pw ta apotelesmata....
Aesmade Δημοσ. 7 Φεβρουαρίου 2008 Δημοσ. 7 Φεβρουαρίου 2008 Αυτό δεν είναι C++, είναι C με μία ξέμπαρκη new από την C++, γενικά είναι λάθος να κάνουμε μίξη ρουτίνων από C σε C++ και vice verca... Κατά τα άλλα έξυπνη σύλληψη. Α ναι sorry για το new, το'χω συνηθίσει και ξεχνάω πως είναι C++... Θα το διορθώσω.
bokarinho Δημοσ. 8 Φεβρουαρίου 2008 Δημοσ. 8 Φεβρουαρίου 2008 Πρόκειται για την τελική έκδοση του προγράμματος το οποίο είναι γραμμένο σε 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... Καλή συνέχεια...
nikopoul Δημοσ. 3 Μαρτίου 2011 Δημοσ. 3 Μαρτίου 2011 · Κρυμμένο από parsifal, 5 Μαρτίου 2011 - Δεν έχει δοθεί λόγος Κρυμμένο από parsifal, 5 Μαρτίου 2011 - Δεν έχει δοθεί λόγος λαθος θεμα σορρυ!!
Προτεινόμενες αναρτήσεις
Αρχειοθετημένο
Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.