Sta Δημοσ. 12 Ιανουαρίου 2005 Δημοσ. 12 Ιανουαρίου 2005 Καλησπέρα, Το πρόγραμμά σου έχει κάποια λάθη, σε γενικές γραμμές τα εξής: Η fscanf που χρησιμοποιείς πρέπει στο τρίτο όρισμα της να έχει το &Line1[...], δηλαδή διεύθυνση. Το τελευταίο στοιχείο του πίνακα είναι το Line1[94] μιάς και η αρίθμηση αρχίζει από το 0. Μάλιστα, ακόμα και με αυτή τη διόρθωση το πρόγραμμα διαβάζει πέρα από το τέλος του αρχείου. Επίσης, όλοι οι χαρακτήρες αποθηκεύονται σε μία συγκεκριμένη θέση και όχι σε διαδοχικές του πίνακα Line1. Έπειτα, πιθανώς εκτυπώνεται ο "χαρακτήρας" EOF που δεν ειναι εκτυπώσιμος. Για να συνηθίσεις σε πιο καθαρές λύσεις σου παραθέτω ένα πρόγραμμα που διαβάζει από το αρχείο με τον τρόπο που πρότεινε πιο πάνω ο DirectX. Το πρόγραμμα αποθηκεύει την πρώτη γραμμή στον πίνακα Line1 τη δεύτερη στο Line2 και μετά τις τυπώνει. Δεν κατάλαβα αν αυτό ακριβώς ήθελες να κάνεις. > #include <stdio.h> #include <stdlib.h> void main(void) { int i=0; char c; char Line1[95], Line2[95]; FILE *Cfg = fopen("./config.txt", "rb"); if (Cfg==NULL) { printf("Cannot open file config.txt\n"); return; } while ((c=fgetc(Cfg))!=EOF && i<95) { Line1[i]=c; i++; } i=0; while((c=fgetc(Cfg))!=EOF && i<95) { Line2[i]=c; i++; } for (i=0;i<95;i++) printf("Line1[%d]:%c ",i,Line1[i]); printf("\n"); for (i=0;i<95;i++) printf("Line2[%d]:%c ",i,Line2[i]); }
Stilewag Δημοσ. 12 Ιανουαρίου 2005 Μέλος Δημοσ. 12 Ιανουαρίου 2005 Afto akrivws ithela na kanw. Telika prepei na ektipwsw tous xaraktires tou Line1[] kai Line2[] enan pros enan. Efxaristw gia tis diorthoseis.
Stilewag Δημοσ. 14 Ιανουαρίου 2005 Μέλος Δημοσ. 14 Ιανουαρίου 2005 meletaw to komati kwdika pou egrapse o Directx, kai einai kapoia pragmata gia ta opoia den eimai sigouros: >#include <stdio.h> int nCharacter, nAlphas = 0; long lFileLen = 0; FILE *InStream, *OutStream; void main(void) { //to fopen("in.txt","rb"), o compiler to eklamvanei san mia timi pleon? //gia afto to "sigkrinei" me to NULL if((InStream=fopen("in.txt","rb"))==NULL) { printf(" Cannot open in.txt for read!\n"); return; //dokimasa na aferesw to return kai apla to programma sinexeise, pws //stamataei to programma? pws prepei na to fantastw } if((OutStream=fopen("out.txt","wb"))==NULL) { //giati einai aparetito na kleisei to arxeio? fclose(InStream); printf(" Cannot create out.txt!\n"); return; } //o nCharacter den einai int? pws diavazei enan xaraktira (char)? //kserw oti mporeis na kaneis ena " myCharacter++ " se mia metavliti //typou char, alla ginetai to antistrofo? //alaksa to nCharacter se char, kai to programma doulepse akrivws //me ton idio tropo (oute kan warning)... while((nCharacter=fgetc(InStream))!=EOF) { lFileLen++; fputc(nCharacter,OutStream); if(nCharacter=='a'){ nAlphas++; } } fclose(InStream); fclose(OutStream); printf(" File length: %ld\n",lFileLen); printf(" Alpha count : %d\n",nAlphas); }
Sta Δημοσ. 15 Ιανουαρίου 2005 Δημοσ. 15 Ιανουαρίου 2005 Καλησπέρα και πάλι, κοίτα τις επεξηγήσεις παρακάτω: > #include <stdio.h> int nCharacter, nAlphas = 0; long lFileLen = 0; FILE *InStream, *OutStream; void main(void) { //to fopen("in.txt","rb"), o compiler to eklamvanei san mia timi pleon? //gia afto to "sigkrinei" me to NULL //Η fopen() epistrefei ena deikth sto file pou anoikse h NULL an apetyxe //Ayth h timh apo8hkeyetai sto InStream //kai epeita sygrinetai me to NULL if((InStream=fopen("in.txt","rb"))==NULL) { printf(" Cannot open in.txt for read!\n"); return; //dokimasa na aferesw to return kai apla to programma sinexeise, pws //stamataei to programma? pws prepei na to fantastw //To return prokalei thn epistrofh ths main, ayto theloume na ginei //epeidh de mporesame na anoiksoume to arxeio "in.txt" } if((OutStream=fopen("out.txt","wb"))==NULL) { //giati einai aparetito na kleisei to arxeio? //Dioti exei anoiksei pio panw //Genika prepei na kleineis osa arxeia exeis anoiksei fclose(InStream); printf(" Cannot create out.txt!\n"); return; } //o nCharacter den einai int? pws diavazei enan xaraktira (char)? //kserw oti mporeis na kaneis ena " myCharacter++ " se mia metavliti //typou char, alla ginetai to antistrofo? //alaksa to nCharacter se char, kai to programma doulepse akrivws //me ton idio tropo (oute kan warning)... //O nCharacter 8a eprepe na einai tupou char //Vevaia kai int pou einai den uparxei kapoio provlhma //Mporeis na kaneis nCharacter++ kai se char kai se int //Na exeis upopsh sou oti genika ginetai aytomata anagwgh typwn //diladi casting xwris warnings. while((nCharacter=fgetc(InStream))!=EOF) { lFileLen++; fputc(nCharacter,OutStream); if(nCharacter=='a'){ nAlphas++; } } fclose(InStream); fclose(OutStream); printf(" File length: %ld\n",lFileLen); printf(" Alpha count : %d\n",nAlphas); }
Directx Δημοσ. 15 Ιανουαρίου 2005 Δημοσ. 15 Ιανουαρίου 2005 Σωστές οι παρατηρήσεις του Sta, η nCharacter λογικά θα μπορούσε να ορισθεί ως unsigned char δηλαδή ως μεταβλητή τιμών μεταξύ 0 ως 255 όμως κάτι τέτοιο στην περίπτωση του παραπάνω κώδικα δεν μπορεί να εφαρμοσθεί καθώς το EOF ισούται με -1 όταν η unsigned char δεν δέχεται αρνητικές τιμές! Όσον αφορά την char για δήλωση αριθμητικών τιμών του ASCII σετ δεν την συνιστώ σε καμία περίπτωση καθώς το εύρος τιμών της είναι πολύ μικρό δηλαδή -128 ως 127 (αυτό που λέμε και ως 7bit BASIC ASCII SET) οπότε αν συναντήσει πχ. τον ASCII χαρακτήρα 250 θα γίνει Overflow με αποτέλεσμα (λόγο carry set) να γυρίσει σε Underflow (-2), τώρα αν δουλεύεις σε 32bit περιβάλλον εργασίας αυτό μπορεί να περάσει απαρατήρητο αρχικά διότι λόγο της εσωτερικής αρχιτεκτονικής του (καθώς όλοι οι τύποι είναι 32bit εσωτερικά) η τιμή γυρίζει σε 0xFFFFFFFA με το FA(=250) να γράφεται σωστά μεν αλλά ειδικά σε 16bit προγραμματισμό αυτό θα μπορούσε να ήταν μεγάλος πονοκέφαλος καθώς κατέστρεφες το stack σου. Ύστερα μην ξεχνάς ότι ο έλεγχος «!=EOF» (όπου EOF = -1) παύει να ισχύει σωστά λόγο των λανθασμένων τιμών (Overflow) με αποτέλεσμα την εγγραφή ως extra byte του ίδιου του EOF (!) ως 0xFF (255) στο αρχείο εξόδου πράγμα που δεν θα έπρεπε σε καμία περίπτωση να συμβεί… Υ.Γ. Αυτά σε περιβάλλον Windows και Borland C/C++ Builder, δεν έχω πρόχειρη την παλιά Turbo C/C++ μου για DOS ώστε να δω το συγκεκριμένο bug σε τι θα αντίδραση θα οδηγούσε ένα 16μπιτο πρόγραμμα..
Stilewag Δημοσ. 15 Ιανουαρίου 2005 Μέλος Δημοσ. 15 Ιανουαρίου 2005 Ok... twra xathika. Nomiza pws tha tin glitwna, alla den tin glitwnw... :| Paw na agorasw ena vivlio C/C++ Einai kalytera na kanw compile ta programmata mou me tin palia Turbo C gia na vlepw lathi pou den tha evlepa ston Builder Compiler? Y.G.: i Turbo C einai pleon freeware mporeis na tin katevaseis apo http://bdn.borland.com/museum/
Sta Δημοσ. 15 Ιανουαρίου 2005 Δημοσ. 15 Ιανουαρίου 2005 Πολύ εύστοχο το σχόλιο του φίλου Directx. Πάντως αν μιλάμε για το βασικό ASCII (7-bits) και με ορισμό char πιστεύω πως δεν υπάρχει πρόβλημα. Η σύγκριση με το EOF (-1) γίνεται κανονικά.
Προτεινόμενες αναρτήσεις
Αρχειοθετημένο
Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.