THMMY.gr

Ηλεκτρονικοί Υπολογιστές και Τεχνικά Θέματα => Προγραμματισμός (C, VB, Delphi, PHP, ASP...) => Topic started by: Nessa NetMonster on April 30, 2008, 12:42:44 pm



Title: Χαρακτήρας EOF μέσα σε αρχείο
Post by: Nessa NetMonster on April 30, 2008, 12:42:44 pm
Πώς μπορώ να διαβάσω ένα αρχείο όταν μέσα εμφανίζεται ο χαρακτήρας EOF;

Χρησιμοποιώ C, αλλά μάλλον δεν έχει σημασία.


Title: Re: Χαρακτήρας EOF μέσα σε αρχείο
Post by: bakeneko on April 30, 2008, 13:10:20 pm
Τι εννοείς;


Title: Re: Χαρακτήρας EOF μέσα σε αρχείο
Post by: Nessa NetMonster on April 30, 2008, 13:49:50 pm
Θέλω να αποθηκεύσω κάπου τις τιμές των χαρακτήρων που περιέχονται σε ένα αρχείο, αλλά δε μπορώ να το διαβάσω όλο γιατί μέσα κάπου εμφανίζεται ο χαρακτήρας End of file.


Title: Re: Χαρακτήρας EOF μέσα σε αρχείο
Post by: Aurelius on April 30, 2008, 13:52:47 pm
Ε? Αν υπαρχει το eof τελειωνει το αρχειο ουτως η αλλως. Οι τιμες ειναι αποθηκευμενες πιο μετα απο αυτον τον χαρακτηρα? Αυτο εννοεις?


Title: Re: Χαρακτήρας EOF μέσα σε αρχείο
Post by: bakeneko on April 30, 2008, 13:55:17 pm
Μετέφερε το EOF στο τέλος του αρχείου...


Title: Re: Χαρακτήρας EOF μέσα σε αρχείο
Post by: Nessa NetMonster on April 30, 2008, 13:55:45 pm
Πώς θα τον μεταφέρω αν δε μπορώ να τον διαβάσω; ::)


Title: Re: Χαρακτήρας EOF μέσα σε αρχείο
Post by: Nessa NetMonster on April 30, 2008, 13:56:24 pm
Εξάλλου το αρχείο θέλω να το διαβάσω, όχι να το χαλάσω. Για ανάγνωση το ανοίγω.


Title: Re: Χαρακτήρας EOF μέσα σε αρχείο
Post by: bakeneko on April 30, 2008, 13:57:43 pm
Αν θες να το διαβάσεις και μετά το EOF πρέπει να το επεξεργαστείς (με τον αγαπημένο σου editor) και να μεταφέρεις το EOF στο τέλος!


Title: Re: Χαρακτήρας EOF μέσα σε αρχείο
Post by: Aurelius on April 30, 2008, 14:04:24 pm
Γινεται ενα αρχειο να εχει πολλα eof? Τεσπα.

Ειναι αγνωστο αρχειο? Π.χ. ξερεις το μεγεθος του ή ποσα eof εχει? Αν ναι, δεν μπορεις να βαλεις ενα if και να κανεις ελεγχο αν ειναι το πρωτο?


Title: Re: Χαρακτήρας EOF μέσα σε αρχείο
Post by: bakeneko on April 30, 2008, 14:15:04 pm
Δε νομίζω ότι έχει πρακτικό νόημα να έχεις πάνω από 1 eof... Με το πρώτο που συναντάει όλα τα παρακάτω είναι σαν να μην υπάρχουν... I think...


Title: Re: Χαρακτήρας EOF μέσα σε αρχείο
Post by: Nessa NetMonster on April 30, 2008, 14:16:34 pm
Ξέρω το μέγεθός του.

Rattlehead το θέμα είναι να μπορώ να ανοίγω τέτοια αρχεία και χωρίς να χρειαστεί να τα ανοίγω κάθε φορά και με editor... εξάλλου πώς θα ξέρω να καταγράψω σε ποιες θέσεις υπήρχε το EOF αν το ανοίξω αλλαγμένο;


Title: Re: Χαρακτήρας EOF μέσα σε αρχείο
Post by: Nessa NetMonster on April 30, 2008, 14:18:12 pm
Το θέμα είναι να καταφέρω να διαβάσω παρακάτω, όχι να καταλάβω αν έφτασα στο πραγματικό τέλος. Το πραγματικό τέλος θα το καταλάβω έτσι κι αλλιώς από το μέγεθος.


Title: Re: Χαρακτήρας EOF μέσα σε αρχείο
Post by: Verminoz on April 30, 2008, 14:25:19 pm
Λοιπόν για να βάλουμε τα πράγματα στη θέση τους. Το eof δεν είναι χαρακτήρας!! Κατά συνέπεια δε φαίνεται σε κανέναν editor!

To eof είναι μία ένδειξη η οποία μάλιστα είναι ακέραιος αριθμός ότι ο seek pointer (με την κυριολεκτική έννοια, μη το μπερδέψετε με τους pointer της C) έχει φτάσει στο τέλος του αρχείου. Το πιο κοινό λάθος που συμβαίνει στην περίπτωση αυτή είναι να ψάχνεις την εμφάνιση του eof παίρνοντας έναν-έναν τους χαρακτήρες και συγκρίνοντας τους με το eof. Η C μετατρέπει τον 16-bit integer σε character ο οποίος αντιστοιχεί σε κάποιον άλλο χαρακτήρα και δεν βρίσκεις ποτέ eof!

Για του λόγου το αληθές. Αυτό είναι λάθος:
Quote
char c;
 while ((c = getchar()) != EOF) {
     putchar(c);
 }
Αυτό είναι το σωστό
Quote
int c;
 while ((c = getchar()) != EOF) {
     putchar(c);
 }

Πάντως για χαρακτήρες μετά το eof πρώτη φορά ακούω!


Title: Re: Χαρακτήρας EOF μέσα σε αρχείο
Post by: lambros on April 30, 2008, 14:35:01 pm
Βασικά νομίζω ότι χρειάζεσαι την συνάρτηση feof. Δηλαδή είναι η συνάρτηση int feof(*fp);
Επιστρέφει 0 αν δεν συναντήσει το τέλος αρχείου και μη μηδενική τιμή αλλιώς.

Για παράδειγμα :

while(!feof(fp))
{
π.χ. fgets(buf,BUFSIZE,fp)
κτλ.
}

όπου fp ο δείκτης τύπου FILE στο αρχείο.


Title: Re: Χαρακτήρας EOF μέσα σε αρχείο
Post by: lambros on April 30, 2008, 14:40:59 pm
Επίσης να επισημάνω ότι όταν ανοίγεις ένα αρχείο σαν δυαδικό το EOF δεν δουλεύει (Το EOF είναι μια συμβολική σταθερά και ισούται με -1).


Title: Re: Χαρακτήρας EOF μέσα σε αρχείο
Post by: kanele on April 30, 2008, 15:32:27 pm
   Αν δε κάνω λάθος, στο ANSI C, The Programming Language του Ritchie
(υπάρχει και στην Αλεξάνδρεια),

έχει αρκετά παραδειγματάκια όσον αφορά, γενικά, το διάβασμα αρχείων και το ΕΟF.

   Τσέκαρε το! :)


Title: Re: Χαρακτήρας EOF μέσα σε αρχείο
Post by: bakeneko on April 30, 2008, 15:42:23 pm
Κατά συνέπεια δε φαίνεται σε κανέναν editor!
Σε ορισμένα σκιπτάκια, π.χ. tcl, φαίνεται και μπορείς να το βάλεις όπου θες! :P


Title: Re: Χαρακτήρας EOF μέσα σε αρχείο
Post by: Nessa NetMonster on April 30, 2008, 15:48:45 pm
Η συνάρτηση feof δε σου δείχνει το τέλος του αρχείου, σου δείχνει απλά πού υπάρχει EOF.

Εγώ διαβάζω έναν έναν τους χαρακτήρες, αλλά μετά από λίγο δε μπορεί να διαβάσει άλλο γιατί έχει σκαλώσει σε ένα σημείο και μου βγάζει συνέχεια τον ίδιο. Όταν δοκιμάζω με Quickbasic, στο σημείο αυτό μου βγάζει σφάλμα "input past end of file".


Title: Re: Χαρακτήρας EOF μέσα σε αρχείο
Post by: Aurelius on April 30, 2008, 15:50:04 pm
Πως γινεται ενα αρχειο να εχει eof στην μεση? Ποιος το φτιαχνει?


Title: Re: Χαρακτήρας EOF μέσα σε αρχείο
Post by: Nessa NetMonster on April 30, 2008, 15:56:35 pm
 ^dontknow^

Στο Notepad++ έχει το χαρακτήρα SUB και μετά το χαρακτήρα ESC.


Title: Re: Χαρακτήρας EOF μέσα σε αρχείο
Post by: Verminoz on April 30, 2008, 16:43:03 pm
Τα SUB και ESC είναι ειδικοί χαρακτήρες του κώδικα ASCII. Επαναλαμβάνω το eof δεν είναι χαρακτήρας. Αν πας να το ερμηνεύσεις έτσι θα προκύψει κάτι άσχετο λόγω στρογγυλοποίησης από ακέραιο!

Συνεχίζω να πιστεύω ότι δε γίνεται να υπάρχει end of file μέσα στο αρχείο. Αυτό που συμβαίνει με κάποιες γλώσσες ίσως είναι ότι γενικά το eof μπορεί να σημαίνει κάποιο σφάλμα στην ανάγνωση....

Κατά συνέπεια δε φαίνεται σε κανέναν editor!
Σε ορισμένα σκιπτάκια, π.χ. tcl, φαίνεται και μπορείς να το βάλεις όπου θες! :P

ε? :P


Title: Re: Χαρακτήρας EOF μέσα σε αρχείο
Post by: Nessa NetMonster on April 30, 2008, 17:42:17 pm
ΟΚ... πώς διαβάζω λοιπόν το SUB χωρίς να νομίσει ο υπολογιστής ότι έφτασε στο τέλος του αρχείου;


Title: Re: Χαρακτήρας EOF μέσα σε αρχείο
Post by: SolidSNK on April 30, 2008, 18:03:09 pm
Συμφωνώ με Kenny και Aurelius... για κάτσε να κάνω λίγο κώδικα μιας και :P


Title: Re: Χαρακτήρας EOF μέσα σε αρχείο
Post by: lambros on April 30, 2008, 18:24:38 pm
Η συνάρτηση feof δε σου δείχνει το τέλος του αρχείου, σου δείχνει απλά πού υπάρχει EOF.

Εγώ διαβάζω έναν έναν τους χαρακτήρες, αλλά μετά από λίγο δε μπορεί να διαβάσει άλλο γιατί έχει σκαλώσει σε ένα σημείο και μου βγάζει συνέχεια τον ίδιο. Όταν δοκιμάζω με Quickbasic, στο σημείο αυτό μου βγάζει σφάλμα "input past end of file".
From Wikipedia, the free encyclopedia

feof is a C function belonging to the ANSI C standard library, and declared in the file stdio.h. Its primary purpose is to distinguish between cases where a stream operation has reached the end of a file and cases where the "EOF" (End Of File) error message has simply been returned as a default error message, without the end of the file actually being reached.

[edit] Function Prototype

The function is used with syntax as follows:

int feof(FILE *stream_pointer);

It takes one argument: a pointer to the FILE structure of the stream to check.

[edit] Return value

The return value of the function is an integer. A nonzero value signifies that the end of the file has been reached; a value of zero signifies that it has not.

[edit] Example code

#include <stdio.h>
 
int main(int argc, char **argv) {
 
    FILE *my_file;
 
    my_file = fopen("file.txt","r");
 
    while(!feof(my_file)) {
        /* [...End of file not reached, do something with it...] */
    }
 
    fclose(my_file);
 
    return 0;
}

Νομίζω πως η feof βρίσκει το τέλος του αρχείου και όχι την EOF σταθερά . Δοκίμασες με feof και δεν σου δούλεψε ?


Title: Re: Χαρακτήρας EOF μέσα σε αρχείο
Post by: Nessa NetMonster on April 30, 2008, 18:28:33 pm
Μα η feof μου βγαίνει αληθής, ενώ ξέρω ότι έχει κι άλλο.


Title: Re: Χαρακτήρας EOF μέσα σε αρχείο
Post by: SolidSNK on April 30, 2008, 18:32:35 pm
Μα αυτό δε γίνεται!!!

Μπορείς να δείξεις κώδικα και το αρχείο (η κάποιο παρόμοιο αν μπορείς) για να δούμε του λόγου το αληθές??

Το μοναδικό που μου έρχεται, είναι αν προσπαθεί να διαβάσει κανένα περίεργο η non-printable χαρακτήρα και γίνεται καμια κουταμάρα... αλλά αυτό το λέω από διαίσθηση. Σε windows πάντα έτσι? Για βοήθα μας λίγο νεσσα :)


Title: Re: Χαρακτήρας EOF μέσα σε αρχείο
Post by: lambros on April 30, 2008, 18:33:50 pm
Βασικά το προβλήμα μπορεί να είναι και αλλού , ισώς να μην αποθηκευείς σωστά τους χαρακτηρές που διαβάζεις απο το αρχείο ? Μπορείς να ποστάρεις τον κώδικα ?

Μα αυτό δε γίνεται!!!

Μπορείς να δείξεις κώδικα και το αρχείο (η κάποιο παρόμοιο αν μπορείς) για να δούμε του λόγου το αληθές??

Το μοναδικό που μου έρχεται, είναι αν προσπαθεί να διαβάσει κανένα περίεργο η non-printable χαρακτήρα και γίνεται καμια κουταμάρα... αλλά αυτό το λέω από διαίσθηση. Σε windows πάντα έτσι? Για βοήθα μας λίγο νεσσα :)

+1


Title: Re: Χαρακτήρας EOF μέσα σε αρχείο
Post by: Nessa NetMonster on April 30, 2008, 18:43:40 pm
Ο αριθμός των bytes στο αρχείο ισούται με datanum. Ο sc είναι pointer σε char, ο fp είναι pointer στο αρχείο που διαβάζω και ο si είναι πίνακας int. Αγνοήστε το if block, το θέμα είναι ότι όταν βάζω breakpoint αμέσως μετά το if (feof(fp))printf("%c",(*sc)) αρχίζει να μου εκτυπώνει "G" μετά από λίγες εκτελέσεις του βρόχου ενώ το αρχείο είναι τεράστιο στην πραγματικότητα. Το G είναι το τελευταίο γράμμα πριν το SUB, οπότε νομίζω ότι εκεί γίνεται η ζημιά.

for (i=0;i<datanum;i++){
   fscanf(fp,"%c",sc);
   if (feof(fp))printf("%c",(*sc));
   if (i%2)
   si[i/2]+=(int)16*(*sc);
   else
   si[i/2]=(int)(*sc);
}


Title: Re: Χαρακτήρας EOF μέσα σε αρχείο
Post by: Καμένος on April 30, 2008, 19:37:43 pm
Σύμφωνα με ότι είπε ο Kenny το διαβάζεις σαν χαρακτήρα και δεν πρέπει .. Δοκίμασε να το διαβάσεις σαν ακέραιο.. Ατί για %c βάλε το %d (?? δε θυμάμαι και ποιο είναι.. ποιος χρησιμοποιεί fscanf??)


Title: Re: Χαρακτήρας EOF μέσα σε αρχείο
Post by: lambros on April 30, 2008, 19:43:34 pm
Ο αριθμός των bytes στο αρχείο ισούται με datanum. Ο sc είναι pointer σε char, ο fp είναι pointer στο αρχείο που διαβάζω και ο si είναι πίνακας int. Αγνοήστε το if block, το θέμα είναι ότι όταν βάζω breakpoint αμέσως μετά το if (feof(fp))printf("%c",(*sc)) αρχίζει να μου εκτυπώνει "G" μετά από λίγες εκτελέσεις του βρόχου ενώ το αρχείο είναι τεράστιο στην πραγματικότητα. Το G είναι το τελευταίο γράμμα πριν το SUB, οπότε νομίζω ότι εκεί γίνεται η ζημιά.

for (i=0;i<datanum;i++){
   fscanf(fp,"%c",sc);
   if (feof(fp))printf("%c",(*sc));
   if (i%2)
   si[i/2]+=(int)16*(*sc);
   else
   si[i/2]=(int)(*sc);
}

Βασικά έτσι όπως το έχεις γράψει η printf δεν εκτελείται καθόλου , πρέπει να έχεις if (!feof(fp))printf("%c",(*sc));
Όσο δεν βρίσκει το τέλος επιστρέφει 0 οπότε για να δουλεύει το if θα πρέπει να βάλεις τον τελεστή !.


Title: Re: Χαρακτήρας EOF μέσα σε αρχείο
Post by: lambros on April 30, 2008, 19:52:26 pm
Βασικά δοκίμασε και αυτό μήπως δουλέψει(αντικατέστησα το For με ένα While )

i=0;

while ((!feof(fp))
        {
         fscanf(fp,"%c",sc);
    printf("%c",(*sc));
    if (i%2)
    si[i/2]+=(int)16*(*sc);
    else
    si[i/2]=(int)(*sc);

          i++;
}


Title: Re: Χαρακτήρας EOF μέσα σε αρχείο
Post by: Nessa NetMonster on April 30, 2008, 19:54:36 pm
Μα εγώ δε θέλω να τα εκτυπώσει όλα, εγώ θέλω να μου εκτυπώσει μόνο τον τελευταίο χαρακτήρα!


Title: deleted
Post by: BOBoMASTORAS on April 30, 2008, 19:57:39 pm
deleted


Title: Re: Χαρακτήρας EOF μέσα σε αρχείο
Post by: SolidSNK on April 30, 2008, 20:07:35 pm
Lambro ο βρόχος αυτός καθαυτός δεν έχει πρόβλημα.

Code:
for (i=0;i<datanum;i++){
   fscanf(fp,"%c",sc);
   if (feof(fp))printf("%c",(*sc));
   if (i%2)
   si[i/2]+=(int)16*(*sc);
   else
   si[i/2]=(int)(*sc);
}

Το θέμα είναι πως με το τρόπο που επέλεξες να διαβάσεις από το αρχείο, με την fscanf, δεν χρειάζεται ούτε η επανάληψη ούτε η feof. Δεν έχω προσπαθήσει κάτι τέτοιο (αν και θα το δω), αλλά εκ πρώτης όψεως η fscanf δε χρησιμοποιείται έτσι!

Από όσο έχω καταλάβει κάπως έτσι

Code:
while ( fscanf(blahblah) != EOF )

θα επανέλθω


Title: Re: Χαρακτήρας EOF μέσα σε αρχείο
Post by: Nessa NetMonster on April 30, 2008, 20:55:27 pm
Οπότε το ερώτημα είναι πως γράφηκε το αρχείο (binary ή text) αλλά κυρίως πως το άνοιξες. Από ότι φαίνεται το αρχείο γράφηκε σε binary mode και εσύ το ανοίγεις σε text mode.

Ναι, σωστό είναι αυτό, απλά θα προτιμούσα να ξεπεραστεί κάπως το πρόβλημα χωρίς να χρειαστεί να το ανοίξω ως binary. Ο κώδικας που χρειάζεται για να πάρω τις τιμές που θέλω είναι πολύ απλός, και θα μου ήταν αρκετά πιο δύσκολο να χειριστώ το αρχείο ως binary.


Title: Re: Χαρακτήρας EOF μέσα σε αρχείο
Post by: lambros on April 30, 2008, 21:14:52 pm
από ότι ξέρω εγώ η τιμή του  eof μπορεί να υπάρχει μέσα σε ένα αρχείο και στη μέση. Για παράδειγμα αν έχεις ανοίξει ένα αρχείο στο 2αδικό και θες να γράψεις τη τιμή που τυχαίνει να αντιστοιχεί στο eof τι θα γίνει? Δε θα τη γράψεις?

Η λύση είναι απλή. Υπάρχει ο ESC (escape character) που ουσιαστικά δηλώνει ότι ο επόμενος χαρακτήρας ΔΕΝ είναι ειδικός. Οπότε όταν θες να γράψεις το EOF απλά γράφεις πρώτα ESC και μετά EOF. Από όσο γνωρίζω όταν έχεις ένα δυαδικό stream αν του πείς να γράψει το χαρακτήρα που αντιστοιχεί στο EOF η C θα γράψει αυτόματα ESC+EOF δηλώνοντας ότι όντως έγραψες τη τιμή του EOF και δε δηλώνεις το τέλος του αρχείου. Το πραγματικό EOF γράφεται όταν κλείνεις το αρχείο.

Ομοίως στην ανάγνωση από ότι ξέρω (αν έχεις δυαδικό stream) αν η C συναντήσει το ESC+EOF τότε σου επιστρέφει τη τιμή του EOF και η συνάρτηση feof() δίνει (ορθά) false.

Βέβαια αν έχεις text stream προφανώς η συνάρτηση feof θα σου δώσει true καθώς δε μπορεί να αναγνωρίσει το συνδυασμό ESC+EOF αλλά τους βλέπει σα διαφορετικούς χαρακτήρες.

Οπότε το ερώτημα είναι πως γράφηκε το αρχείο (binary ή text) αλλά κυρίως πως το άνοιξες. Από ότι φαίνεται το αρχείο γράφηκε σε binary mode και εσύ το ανοίγεις σε text mode.

Υ.γ. Το ερώτημα τώρα είναι τι κάνεις αν όντως θες να γράψεις τη τιμή του ESC.

+1 , μαλλόν δεν γίνεται να το αποφύγεις το binary άνοιγμα .


Title: Re: Χαρακτήρας EOF μέσα σε αρχείο
Post by: lambros on April 30, 2008, 21:21:26 pm
Ο αριθμός των bytes στο αρχείο ισούται με datanum. Ο sc είναι pointer σε char, ο fp είναι pointer στο αρχείο που διαβάζω και ο si είναι πίνακας int. Αγνοήστε το if block, το θέμα είναι ότι όταν βάζω breakpoint αμέσως μετά το if (feof(fp))printf("%c",(*sc)) αρχίζει να μου εκτυπώνει "G" μετά από λίγες εκτελέσεις του βρόχου ενώ το αρχείο είναι τεράστιο στην πραγματικότητα. Το G είναι το τελευταίο γράμμα πριν το SUB, οπότε νομίζω ότι εκεί γίνεται η ζημιά.

for (i=0;i<datanum;i++){
   fscanf(fp,"%c",sc);
   if (feof(fp))printf("%c",(*sc));
   if (i%2)
   si[i/2]+=(int)16*(*sc);
   else
   si[i/2]=(int)(*sc);
}

Πάντως αφού ξέρεις τον ακριβή αριθμό Bytes του αρχείου (στη μεταβλητή datanum) δεν χρειάζεται να χρησιμοποιήσεις το eof . Όταν τελειώσει ο βρόχος for θα έχεις φτάσει και στο τέλος του αρχείου . Δηλαδή μήπως γίνεται έτσι:
for (i=0;i<datanum;i++){
   fscanf(fp,"%c",sc);
   if (i%2)
   si[i/2]+=(int)16*(*sc);
   else
   si[i/2]=(int)(*sc);
}
printf("%c",(*sc));
Δηλαδή βάζεις την printf όταν τελειώσει ο βρόχος .


Title: Re: Χαρακτήρας EOF μέσα σε αρχείο
Post by: Nessa NetMonster on April 30, 2008, 21:51:20 pm
Μα όταν τελειώσει ο βρόχος for δε θα βρίσκομαι στο τέλος του αρχείου, θα βρίσκομαι πριν το πρώτο EOF.


Title: deleted
Post by: BOBoMASTORAS on May 01, 2008, 13:51:08 pm
deleted


Title: Re: Χαρακτήρας EOF μέσα σε αρχείο
Post by: Nessa NetMonster on May 01, 2008, 17:30:46 pm
Φτου... :(

Ε τι να κάνουμε... binary τότε ::)

Ευχαριστώ πάντως.