gegounaris Δημοσ. 30 Ιουνίου 2007 Δημοσ. 30 Ιουνίου 2007 καλημέρα... εδώ και καιρό προσπαθώ να βρω λύση σε κάτι, όποιος μπορεί να βοηθήσει, ευπρόσδεκτος! έχω ένα .txt αρχείο το οποίο έχει κάμποσες γραμμές και εγώ θέλω να διαβάζω μόνο την τελευταία γραμμή κάθε φορά. Πώς μπορώ να το πετύχω αυτό? έχω δοκιμάσει διάφορα. η τελευταία γραμμή που θέλω να να διαβάζω έχει τη μορφή 25042007 1830 0,3 0,3 0,3 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 20,301 20,505 20,386 0,059 0,0 0,0 0,0 0,0 0,0 2,564 0,206 0,217 15,0 15,0 15,0 0,0 Εκτός των 2 πρώτων τιμών οι υπόλοιπες είναι float, πώς μπορώ να την περάσω σε ένα πίνακα?
bird Δημοσ. 30 Ιουνίου 2007 Δημοσ. 30 Ιουνίου 2007 Καλημέρα, Υπάρχουν διάφοροι τρόποι να το κάνεις αυτό. Θα μπορούσες με την fgets να διαβάζεις μια μια γραμμή μέχρι το τέλος, και μετά μέσα από το τελευταίο string να διαβάσεις τους αριθμούς της τελευταίας γραμμής. Αλλοιώς θα μπορούσες να διαβάσεις ανά γραμμή το αρχείο και να αυξάνεις έναν μετρητή (πχ. line_no)κάθε φορά. Στη συνέχεια κάνεις rewind και διαβάζεις line_no-1 γραμμές. Οπότε μετά μπορείς με μία fscanf να διαβάσεις τους αριθμούς σου. Τώρα αν θέλεις να βάλεις όλους τους αριθμούς σε ένα πίνακα, τους διαβάζεις όλους σαν float και τους αποθηκεύεις. Αλλοιώς αν θέλεις να έχεις χωριστά τους Integer, τους διαβάζεις πρώτα χωριστά και μετά τους άλλους σε πίνακα. Δεν ξέρω αν βοήθησα, αλλά θα μπορούσες να μας βάλεις κάποιο κώδικά σου να τον δούμε...
Directx Δημοσ. 30 Ιουνίου 2007 Δημοσ. 30 Ιουνίου 2007 Το παρακάτω γρήγορα γραμμένο πρόγραμμα, μεταβαίνει στο τέλος ενός αρχείου κειμένου και αναγνωρίζει ως έναρξη της τελευταία γραμμής του αρχείου οτιδήποτε ακολουθεί ύστερα από την εμφάνιση του δεύτερο (διότι η γραμμή μπορεί να τελειώνει με \n -συνήθως) χαρακτήρα ʽ\nʼ (= νέα γραμμή στην C) που μπορεί να υπάρχει σε αυτό, το ίδιο συμβαίνει επίσης αν φτάσουμε απλά στην αρχή του αρχείου δηλαδή στο μηδέν (lLength==0). Ύστερα με βάση την θέση αυτού του δεύτερου \n υπολογίζει το μέγεθος της γραμμής σε bytes (lLineLen) και δοκιμάζει να την φορτώσει (fread) στην ανάλογα δεσμευμένη (calloc) μνήμη. Μετά από αυτό ξεκινά να επεξεργάζεται τα δεδομένα της γραμμής ανά κόμμα «,» (strtok). Οι δυο πρώτες τιμές «25042007» και «1830» αφού χωρισθούν με τα ανάλογα «,» (memchr) αποθηκεύονται στον πίνακα long αριθμών (lTable) ενώ οι υπόλοιπες στο πίνακα float αριθμών (ptrFloat) ο οποίος δεσμεύεται δυναμικά (realloc). Όταν οι float τιμές περιλαμβάνουν μεταξύ τους κενό (space) πχ. «217 15» θεωρώ ότι εννοείς «217.15» οπότε αλλάζω το κενό με «.» (memchr). Προσοχή, η αποθηκεύσει των float τιμών γίνεται με την atof δίχως rounding παρʼ όλο που στο τέλος τις εκτυπώνω (lPrintIdx for-loop) με round στα 2 ψηφία μετά την υποδιαστολή.. Ακολουθεί ο κώδικας, γραμμένος σε CodeGear C/C++ Builder 6: > /*-Float & Integers table from file (dx) version 2---------------------------*/ #include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef __BORLANDC__ #pragma hdrstop #endif /*---------------------------------------------------------------------------*/ #ifdef __BORLANDC__ #pragma argsused #endif int main(int argc, char* argv[]) { FILE *Stream; int nLongTable = 0; long lLength, lFileLength, lLineLen, lPrintIdx, lTable[2], lFloatTable = 1; char *ptrArray = NULL, *ptrToken= NULL, *ptrTokenDivider; float *ptrFloat = NULL; if((Stream=fopen(argv[1],"rb"))==NULL) printf(" Cannot open file for read - %s\n",argv[1]); else { /* Find file length the ANSI-C way ... */ if(fseek(Stream,0,SEEK_END)!=0) printf(" Cannot seek to EOF - %s\n",argv[1]); else if((lLength=ftell(Stream))==-1L) printf(" Cannot find file length - %s\n",argv[1]); else { /* Find last line length (line should have a leading \n) */ lFileLength = lLength; for(;lLength>0;lLength--) { static int nNewLineCount = 0, nChar = 0; fseek(Stream,lLength,SEEK_SET); if((nChar = fgetc(Stream))=='\n') if(++nNewLineCount>1) break; } lLineLen = lFileLength - lLength; if((ptrArray=(char*)calloc(lLineLen+1,sizeof(char)))==NULL) printf(" Not enough memory!\n"); else { /* Load Line */ if(fseek(Stream,lLength,SEEK_SET)!=0) printf(" Cannot seek to Line offset - %s\n",argv[1]); else { if(fread(ptrArray,lLineLen,1,Stream)!=1) printf(" Cannot read line to memory - %s\n",argv[1]); else { /* version 2:Make sure that the first two integers are , seperated */ for(nLongTable=0;nLongTable<2;nLongTable++) { ptrTokenDivider = (char*)memchr(ptrArray,' ',strlen(ptrArray)); if(ptrTokenDivider!=NULL) ptrArray[ptrTokenDivider-ptrArray] = ','; } nLongTable = 0; /* The array consits of floats seperated with , but the first two entries are integers! */ if((ptrToken = strtok(ptrArray,","))!=NULL) /* version 2:" "->"," (bug-fix) */ { do{ /* Store Integer into Long table */ if(nLongTable<2) { lTable[nLongTable++] = atoi(ptrToken); continue; } /* Set space to dot => 217 15 => 217.15 */ ptrTokenDivider = memchr(ptrToken,' ',strlen(ptrToken)); if(ptrTokenDivider!=NULL) ptrToken[ptrTokenDivider-ptrToken] = '.'; /* Store float into Float table */ ptrFloat = (float*)realloc(ptrFloat,lFloatTable*sizeof(float)); memset(&ptrFloat[lFloatTable-1],0,sizeof(float)); ptrFloat[lFloatTable-1] = atof(ptrToken); lFloatTable++; }while((ptrToken=strtok(NULL,","))!=NULL); } /* Print integer (long) table */ printf(" Integer Table:\n"); for(lPrintIdx=0;lPrintIdx<nLongTable;lPrintIdx++) printf("[%.2d] = %ld\n",lPrintIdx,lTable[lPrintIdx]); printf("\n"); /* Print float table with up to 2 digits accurancy */ printf(" Float Table:\n"); for(lPrintIdx=0;lPrintIdx<lFloatTable-1;lPrintIdx++) printf("[%.2d] = %.2f\n",lPrintIdx,ptrFloat[lPrintIdx]); } } } } } free(ptrArray); free(ptrFloat); fclose(Stream); printf(" Press Enter to quit..."); fgetc(stdin); return 0; } /*---------------------------------------------------------------------------*/ Ακολουθεί ένα test-input: > 1 2 3 4 5 6 83 3 23 324 29 23492 25042007 1830 0,3 0,3 0,3 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 20,301 20,505 20,386 0,059 0,0 0,0 0,0 0,0 0,0 2,564 0,206 0,217 15,0 15,0 15,0 0,0 Και το output: > Integer Table: [00] = 25042007 [01] = 1830 Float Table: [00] = 0.00 [01] = 3.00 [02] = 3.00 [03] = 3.00 [04] = 0.00 [05] = 0.00 [06] = 0.00 [07] = 0.00 [08] = 0.00 [09] = 0.00 [10] = 0.00 [11] = 0.00 [12] = 0.20 [13] = 301.20 [14] = 505.20 [15] = 386.00 [16] = 59.00 [17] = 0.00 [18] = 0.00 [19] = 0.00 [20] = 0.00 [21] = 0.20 [22] = 564.00 [23] = 206.00 [24] = 217.15 [25] = 0.15 [26] = 0.15 [27] = 0.00 [28] = 0.00 Press Enter to quit... Προσέξτε για αβλεψίες (Bugs) – δεν έχω δοκιμάσει όλα τα πιθανά “input scenarios”. Καλή συνέχεια!
m1cRo Δημοσ. 30 Ιουνίου 2007 Δημοσ. 30 Ιουνίου 2007 καλημέρα...εδώ και καιρό προσπαθώ να βρω λύση σε κάτι, όποιος μπορεί να βοηθήσει, ευπρόσδεκτος! έχω ένα .txt αρχείο το οποίο έχει κάμποσες γραμμές και εγώ θέλω να διαβάζω μόνο την τελευταία γραμμή κάθε φορά. Πώς μπορώ να το πετύχω αυτό? έχω δοκιμάσει διάφορα. η τελευταία γραμμή που θέλω να να διαβάζω έχει τη μορφή 25042007 1830 0,3 0,3 0,3 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 20,301 20,505 20,386 0,059 0,0 0,0 0,0 0,0 0,0 2,564 0,206 0,217 15,0 15,0 15,0 0,0 Εκτός των 2 πρώτων τιμών οι υπόλοιπες είναι float, πώς μπορώ να την περάσω σε ένα πίνακα? Κάτι πολύ απλό που σκέφτηκα: > #include "stdio.h" #include "conio.h" #include "string.h" int main(int argc, char* argv[]) { FILE *fp; fp=fopen("text.txt","r"); fseek(fp,0L,SEEK_END); int size=ftell(fp); char *buf=new char[size]; rewind(fp); fread(buf,size,1,fp); char *pos=buf; char *res=NULL; int result=0; bool end=false; while(!end){ res=pos; pos=strchr(pos+1,'\n'); if(pos==NULL){ end=true; } result=res-buf; } puts(buf+result); getch(); return 0; } το έγγραφα σε notepad οποτε μην με κράζετε
gegounaris Δημοσ. 30 Ιουνίου 2007 Μέλος Δημοσ. 30 Ιουνίου 2007 Σας ευχαριστώ πολύ όλους για την βοήθεια σας. Όταν οι float τιμές περιλαμβάνουν μεταξύ τους κενό (space) πχ. «217 15» θεωρώ ότι εννοείς «217.15» οπότε αλλάζω το κενό με «.» (memchr). Directx, το κενό ανάμεσα στους αριθμούς δηλώνει ότι είναι άλλος αριθμός.
Directx Δημοσ. 30 Ιουνίου 2007 Δημοσ. 30 Ιουνίου 2007 Οκ: > /*-Float & Integers table from file (dx) version 3---------------------------*/ #include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef __BORLANDC__ #pragma hdrstop #endif /*---------------------------------------------------------------------------*/ #ifdef __BORLANDC__ #pragma argsused #endif int main(int argc, char* argv[]) { FILE *Stream; int nLongTable = 0; long lLength, lFileLength, lLineLen, lPrintIdx, lTable[2], lFloatTable = 1; char *ptrArray = NULL, *ptrToken= NULL, *ptrTokenDivider; float *ptrFloat = NULL; if((Stream=fopen(argv[1],"rb"))==NULL) printf(" Cannot open file for read - %s\n",argv[1]); else { /* Find file length the ANSI-C way ... */ if(fseek(Stream,0,SEEK_END)!=0) printf(" Cannot seek to EOF - %s\n",argv[1]); else if((lLength=ftell(Stream))==-1L) printf(" Cannot find file length - %s\n",argv[1]); else { /* Find last line length (line should have a leading \n) */ lFileLength = lLength; for(;lLength>0;lLength--) { static int nNewLineCount = 0, nChar = 0; fseek(Stream,lLength,SEEK_SET); if((nChar = fgetc(Stream))=='\n') if(++nNewLineCount>1) break; } lLineLen = lFileLength - lLength; if((ptrArray=(char*)calloc(lLineLen+1,sizeof(char)))==NULL) printf(" Not enough memory!\n"); else { /* Load Line */ if(fseek(Stream,lLength,SEEK_SET)!=0) printf(" Cannot seek to Line offset - %s\n",argv[1]); else { if(fread(ptrArray,lLineLen,1,Stream)!=1) printf(" Cannot read line to memory - %s\n",argv[1]); else { /* The array consits of floats seperated with , but the first two entries are integers! */ if((ptrToken = strtok(ptrArray," "))!=NULL) /* version 2:" "->"," (bug-fix) */ { do{ /* Store Integer into Long table */ if(nLongTable<2) { lTable[nLongTable++] = atoi(ptrToken); continue; } /* version 3:Set comma to dot => 0,217 => 0.217 (if you use/support setlocale this may become redudant ) */ ptrTokenDivider = (char*)memchr(ptrToken,',',strlen(ptrToken)); if(ptrTokenDivider!=NULL) ptrToken[ptrTokenDivider-ptrToken] = '.'; /* Store float into Float table */ ptrFloat = (float*)realloc(ptrFloat,lFloatTable*sizeof(float)); memset(&ptrFloat[lFloatTable-1],0,sizeof(float)); ptrFloat[lFloatTable-1] = atof(ptrToken); lFloatTable++; }while((ptrToken=strtok(NULL," "))!=NULL); } /* Print integer (long) table */ printf(" Integer Table:\n"); for(lPrintIdx=0;lPrintIdx<nLongTable;lPrintIdx++) printf("[%.2d] = %ld\n",lPrintIdx,lTable[lPrintIdx]); printf("\n"); /* Print float table with up to 2 digits accurancy */ printf(" Float Table:\n"); for(lPrintIdx=0;lPrintIdx<lFloatTable-1;lPrintIdx++) printf("[%.2d] = %.3f\n",lPrintIdx,ptrFloat[lPrintIdx]); } } } } } free(ptrArray); free(ptrFloat); fclose(Stream); printf(" Press Enter to quit..."); fgetc(stdin); return 0; } /*---------------------------------------------------------------------------*/ Ακολουθεί ένα test-input: > 1 2 3 4 5 6 83 3 23 324 29 23492 25042007 1830 0,3 0,3 0,3 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 20,301 20,505 20,386 0,059 0,0 0,0 0,0 0,0 0,0 2,564 0,206 0,217 15,0 15,0 15,0 0,0 Και το output: > Integer Table: [00] = 25042007 [01] = 1830 Float Table: [00] = 0.300 [01] = 0.300 [02] = 0.300 [03] = 0.000 [04] = 0.000 [05] = 0.000 [06] = 0.000 [07] = 0.000 [08] = 0.000 [09] = 0.000 [10] = 0.000 [11] = 0.000 [12] = 20.301 [13] = 20.505 [14] = 20.386 [15] = 0.059 [16] = 0.000 [17] = 0.000 [18] = 0.000 [19] = 0.000 [20] = 0.000 [21] = 2.564 [22] = 0.206 [23] = 0.217 [24] = 15.000 [25] = 15.000 [26] = 15.000 [27] = 0.000 Press Enter to quit... Υ.Γ. Εκτυπώνω με ακρίβεια 3 ψηφίων αντί για 2. Επίσης η ρουτίνα μετατροπής του "," σε "." (memchr) προς χάρην της atof, μπορεί να αφαιρεθεί με την βοήθεια της setlocale (ώστε η atof να αντιλαμβάνεται σωστά το "," ως "." δηλαδή) εφ' όσον όμως υποστηρίζονται τα "Ελληνικά locale" από το σύστημα & compiler. Ελπίζω να φανεί χρήσιμο..
bilco Δημοσ. 1 Ιουλίου 2007 Δημοσ. 1 Ιουλίου 2007 FILE *fp; fp=fopen("text.txt","r"); fseek(fp,0L,SEEK_END); int size=ftell(fp); char *buf=new char; Γενικά δεν είναι καλή πρακτική να φορτώνεις όλο το αρχείο στη μνήμη. Μπορεί να είναι αρκετά μεγάλο.
gegounaris Δημοσ. 2 Ιουλίου 2007 Μέλος Δημοσ. 2 Ιουλίου 2007 Τι κάνει ακριβώς η memchr(); Χρησιμοποιώ Borland C++ Builder 6.0 Enterprise και παίρνω το εξής error. [C++ Error] prog.cpp(81): E2034 Cannot convert 'void *' to 'char *' στο κώδικα: ptrTokenDivider = memchr(ptrToken,',',strlen(ptrToken)); Καμμιά ιδέα?
bilco Δημοσ. 2 Ιουλίου 2007 Δημοσ. 2 Ιουλίου 2007 Βρίσκει έναν χαρακτήρα μέσα σε μια string >ptrTokenDivider = (char*)memchr(ptrToken,',',strlen(ptrToken)); Αν υπάρχει ο ptrTokenDivider είναι η διεύθυνση του πρώτου ',' μέσα στην ptrToken, αλλιώς είναι NULL.
Directx Δημοσ. 2 Ιουλίου 2007 Δημοσ. 2 Ιουλίου 2007 Τι κάνει ακριβώς η memchr(); Χρησιμοποιώ Borland C++ Builder 6.0 Enterprise και παίρνω το εξής error. [C++ Error] prog.cpp(81): E2034 Cannot convert 'void *' to 'char *' στο κώδικα: ptrTokenDivider = memchr(ptrToken,',',strlen(ptrToken)); Καμμιά ιδέα? Ότι σου είπε ο bilco, ψάχνω για την θέση του "," (με pointer arithmetic) και τον αλλάζω σε "." -άλλωστε το εξηγώ στο ανάλογο comment-block πάνω από την συνάρτηση.. Περί του "λάθους" τώρα.. Το "λάθος" προέρχεται διότι δοκιμάζεις να κάνεις compile το λογισμικό μου ως C++ κώδικα οπότε σε αυτή την περίπτωση η C++ θέλει cast στην memchr καθώς επιστρέφει void* σε έναν τύπο char*. Επειδή όμως το έγραψα σε καθαρή C (επιλογή C στον Console Wizard του C++ Builder) το casting δεν είναι πάντα απαραίτητο οπότε διέφυγε της προσοχής μου και φυσικά ο compiler λειτουργώντας σε C mode δεν παραπονέθηκε. Αυτό συμβαίνει αρκετές φορές, οπότε οι C προγραμματιστές εξ' ορισμού αναγκάζονται να βάζουν casts στον κώδικα τους ώστε αυτός να γίνεται compile και από C++ compilers. Διόρθωσα το source για αυτή την περίπτωση.. Καλή συνέχεια!
m1cRo Δημοσ. 2 Ιουλίου 2007 Δημοσ. 2 Ιουλίου 2007 Αν το αρχείο είναι μεγάλο δεν το διαβάζεις από την αρχή αλλα τα η τελευταία bytes .
dop Δημοσ. 3 Ιουλίου 2007 Δημοσ. 3 Ιουλίου 2007 Αυτό συμβαίνει αρκετές φορές, οπότε οι C προγραμματιστές εξ' ορισμού αναγκάζονται να βάζουν casts στον κώδικα τους ώστε αυτός να γίνεται compile και από C++ compilers. Πρέπει κάποιος να είναι τρελός για να κάνει κάτι τέτοιο... Αν θέλει να γίνεται compile και από C++, ας το δηλώσει σαν extern "C". Σε ποια περίπτωση δε θα δούλευε κάτι τέτοιο; Και αν ακόμα ζορίζει τόσο πολύ, ας κάνει wrapper functions/classes γύρω από την C υλοποίηση για να έχει μια κομψή λύση. Κάνοντας casting στην malloc(), calloc() κλπ απαγορεύεις στον compiler να σου υποδείξει σοβαρά λάθη.
Directx Δημοσ. 3 Ιουλίου 2007 Δημοσ. 3 Ιουλίου 2007 Φίλε, τρελός δεν ξέρω αν είμαι - μπορεί Από εκεί και πέρα, ο καθένας όπως διευκολύνεται και φυσικά μην ξεχνάμε πως η κομψότητα είναι υποκειμενική. Όσον αφορά τα σφάλματα που μπορούν να προκύψουν (αν πχ. δεν συμπεριλάβεις την stdlib.h και καλέσεις την malloc type casted για παράδειγμα ή αν αλλάξεις το type δίχως το ανάλογο type cast κατά την ανάπτυξη κτλ..) ευτυχώς εντοπίζονται αυτόματα από το CodeGear IDE μου. Μάλιστα μιας και έθιξες το θέμα: Συμβουλεύω όλους του προγραμματιστές Borland C/C++ Builder και CodeGear Turbo C++ / BDS να ενεργοποιούν κατά το development τον εντοπιστή σφαλμάτων μνήμης CodeGuard καθώς θα τους γλυτώσει από αρκετούς (αλλά όχι όλους) τους μπελάδες σωστής διαχείρισης μνήμης που έχει η C/C++ -σε σπάνιες περιπτώσεις βέβαια μπορεί να τους προκαλέσει μερικούς πονοκεφάλους αλλά σε γενικές γραμμές πιστεύω ότι θα ωφεληθούν
bokarinho Δημοσ. 5 Ιουλίου 2007 Δημοσ. 5 Ιουλίου 2007 Ekana kai egw mia prospatheia gia tin timi twn oplwn an kai den nomizw na sxoliastei apo kanenan, ousiastika moiazei me tin logiki tou DirectX alla den xrisimopoiw fread() poy einai sta diadika arxeia. Emeina stin logiki twn arxeiwn keimenoy. Sigoyra yparxoyn bugs, mias kai den exw xrisimopoiisei CodeGear kai to periballon einai to DevC++ poy den xrisimopoiw Debuger gia eynoitous logoys. (Xali mayrio.) To parakatw logismiko epishs dimiourgei ena arxeio kai to gemizei me oti plirofories theloyme. Briskei tin teleytaia grammi kai tin fortwnei se ena buffer to opoio kai epistrefetai. Stin synexeia mesw mia 3is synartisis ekteloyme tin doyleia poy theloyme se 2 apla bimata, arxika pairnoyme to buffer kai opoy briskoyme ',' to antikathistoyme me '.' kai stin synexeia me temaxisi pairnoyme oloys toys arithmoys. Stin ousia einai i stratigiki toy DirectX poy elyse to problima amesa above me alli morfh se perissoteres grammes kwdika. . > //Version 2. #include <stdio.h> #include <stdlib.h> #include <string.h> //Function Code. int WriteDataToFile(char *filename, int nLines) { if(filename) { FILE *fp = fopen(filename, "w"); if(fp) { int i = 0; char *buffer = (char *)calloc(1024, sizeof(char)); if(buffer) { for(i = 0; i < nLines; i++) { printf("Enter data to write to file:"); if(fgets(buffer, 1024, stdin) != NULL) { if(buffer[strlen(buffer) - 1] == '\n') buffer[strlen(buffer) - 1] = '\0'; if(fprintf(fp, "%s\n", buffer) < 0) { printf("Could not write line %d\n", i); break; } } //Clear buffer. memset(buffer, 0 , strlen(buffer)); } //Release Buffer and close file. free(buffer); fclose(fp); if(i == nLines) return 0; else return -1; } else { printf("Memory Error.\n"); return -2; } } else { printf("File Error, could not open the %s file\n", filename); return -3; } } else { printf("No input filename.\n"); return -4; } } //Function Reads data from file, it reads the last line from file always. char *ReadDataLine(char *filename) { FILE *fpointer; char nChar; int fSize = 0; int i = 3; int j = 0; char *buffer = NULL; char *revBuffer = NULL; fpointer = fopen(filename, "r"); if(fpointer == NULL) { fprintf(stderr, "Error in opening %s\n", filename); return NULL; } if(fseek(fpointer, 0 , SEEK_END) < 0) { printf("Can not find the end of file.\n"); return NULL; } if((fSize = ftell(fpointer)) == -1L) { printf("Can not tell the file size.\n"); return NULL; } //Two alternative choices, move from end backwards, or from the begining fSize - 3, and then backwards. //Watch out, every line holds the terminating '\0' and the '\n' characters. //Rewind two places from the end. fseek(fpointer, -i, SEEK_END); buffer = (char *)calloc(1, sizeof(char)); while((nChar = fgetc(fpointer)) != '\n') { buffer[j++] = nChar; buffer = (char *)realloc(buffer, (j+2) * sizeof(char)); if(buffer == NULL) break; if(fseek(fpointer, -(++i), SEEK_END) < 0) { if(i>fSize) nChar = '\n'; break; } } if(nChar == '\n') buffer[j] = '\0'; else return NULL; //We got the string but it is in reverse order, lets reverse it. fclose(fpointer); revBuffer = (char *)calloc(strlen(buffer)+1,sizeof(char)); for(i = strlen(buffer)-1, j = 0; i >= 0 && j < strlen(buffer); i--) revBuffer[j++] = buffer[i]; //Terminate String. revBuffer[j] = '\0'; //Free buffer. free(buffer); //Return Value. return revBuffer != NULL ? revBuffer : NULL; } float *LoadArrayFromBuffer(char *buffer, int *Asize) { if(buffer) { //Function Variables. int a = 1; int i = 0; int cnt = 0; int dif = 0; char *pToken = NULL; char *nToken = NULL; //Copy Buffer. char *cp = strdup(buffer); //Return Value. float *ptrArray = NULL; ptrArray = (float *)calloc(1, sizeof(float)); if(!ptrArray) { printf("Memory Error.\n"); return NULL; } //Get tokens. //Parse the first two. pToken = strtok(buffer, " "); do { ptrArray[i++] = atoi(pToken); pToken = strtok(NULL, " "); }while(pToken && (ptrArray = (float*)realloc(ptrArray, (a+2) * sizeof(float))) != NULL && i < 2); //Do it in two diffirent stages. nToken = strchr(cp, ','); if(nToken) { while(nToken) { dif = cp - nToken; dif = dif < 0 ? -dif : dif; cp[dif] = '.'; nToken = strchr(nToken+1, ','); } } //Now we have our buffer read with the numbers, strtok in spaces.Remember the 2 numbers. pToken = strtok(cp, " "); if(pToken) { cnt += 1; while(pToken) { if(cnt > 2) { ptrArray = (float*)realloc(ptrArray, (a+=2) * sizeof(float)); ptrArray[i++] = atof(pToken); } pToken = strtok(NULL, " "); cnt += 1; } } //Free helpful buffers. free(cp); //Return Array size. *Asize = i; //and the whole array. return ptrArray; } else return NULL; } int main(int argc, char *argv[]) { int i; int size = 0; float *p = NULL; char *string = NULL; char *filename = "file1.txt"; WriteDataToFile(filename, 5); string = ReadDataLine(filename); printf("\nRead String from file: %s is:%s\n\n",filename, string); p = LoadArrayFromBuffer(string, &size); free(string); for(i = 0; i < size; printf("Array[%d] = %.4f\n", i,p[i]), i++); free(p); system("PAUSE"); return 0; } Typwmena apotelesmata. Enter data to write to file:1 Enter data to write to file:2 Enter data to write to file:3 Enter data to write to file:4 Enter data to write to file:25042007 1830 0,3 0,3 0,3 0,0 0,0 0,0 0,0 0,0 0,0 0, 0 0,0 0,0 20,301 20,505 20,386 0,059 0,0 0,0 0,0 0,0 0,0 2,564 0,206 0,217 15,0 15,0 15,0 0,0 Read String from file: file1.txt is:25042007 1830 0,3 0,3 0,3 0,0 0,0 0,0 0,0 0, 0 0,0 0,0 0,0 0,0 20,301 20,505 20,386 0,059 0,0 0,0 0,0 0,0 0,0 2,564 0,206 0,2 17 15,0 15,0 15,0 0,0 Array[0] = 25042008.0000 Array[1] = 1830.0000 Array[2] = 0.3000 Array[3] = 0.3000 Array[4] = 0.3000 Array[5] = 0.0000 Array[6] = 0.0000 Array[7] = 0.0000 Array[8] = 0.0000 Array[9] = 0.0000 Array[10] = 0.0000 Array[11] = 0.0000 Array[12] = 0.0000 Array[13] = 0.0000 Array[14] = 20.3010 Array[15] = 20.5050 Array[16] = 20.3860 Array[17] = 0.0590 Array[18] = 0.0000 Array[19] = 0.0000 Array[20] = 0.0000 Array[21] = 0.0000 Array[22] = 0.0000 Array[23] = 2.5640 Array[24] = 0.2060 Array[25] = 0.2170 Array[26] = 15.0000 Array[27] = 15.0000 Array[28] = 15.0000 Array[29] = 0.0000 Press any key to continue . . . Den anamenw sxoliasmo etsi kai alliws, grafw kai ayrio mathima, kali synexeia.
gegounaris Δημοσ. 11 Δεκεμβρίου 2007 Μέλος Δημοσ. 11 Δεκεμβρίου 2007 Πώς θα μπορούσα να μετατρέψω τον Integer Table: [01] = 1830 απο long σε string γιατί το συγκεκριμένο αναφέρεται στην ώρα και όταν π.χ. η ώρα είναι 00:10 εγώ παίρνω μόνο την τιμή 10. Έχω δοκιμάσει διάφορα απο το ίνετρνετ αλλά δεν έπαιξε τπτ. Έχει κανείς κάνει κάτι ανάλογο?
Προτεινόμενες αναρτήσεις
Αρχειοθετημένο
Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.