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

Εγγραφή και ανάγνωση αρχείου txt στη C


Giorgos3924

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

Δημοσ.

Καλησπέρα!

Έχω ένα πρόβλημα σε εγγραφή και ανάγνωση δεδομένων σε αρχείο με τη C.

Έχω μια δομή struct που περιέχει 10 πίνακες τύπου char.

η μεταβλητή του struct είναι επίσης πίνακας.

Έτσι έχω έναν πίνακα 10 θέσεων πχ, που περιέχει ετικέτες με κάποια στοιχεία.

Τα οποία θέλω να περάσω στο αρχείο.

Το πρόβλημα είναι ότι καθώς τυπώνω τα στοιχεία στο αρχείο ξεχωρίζοντας τα με "#"

ανάμεσα σε κάποια από αυτά δεν τυπώνεται η "#" και εμφανίζονται ενωμένα.

Δηλαδή

Αντί να εμφανιστούν ως:

>1# electronica # thesaloniki # 342415134 # 6900000000 # 12.33 # 12/02/2003 # 150E

Εμφανίζονται έτσι:

>1# electronica # thesaloniki # 342415134 # 690000000012.3312/02/2003150E # 12.3312/02/2003150E # 12/02/2003150E # 150E

 

Ο κώδικας του προγράμματος είναι μια χαρά.

>     fp=fopen("book.txt","w");
    fprintf(fp,"%d# ", x+1);
    fputs(book[x].eteria,fp);
    fprintf(fp," # ");
    fputs(book[x].address,fp);
    fprintf(fp," # ");
    fputs(book[x].afm,fp);
    fprintf(fp," # ");
    fputs(book[x].thl,fp);
    fprintf(fp," # ");
    fputs(book[x].time,fp);
    fprintf(fp," # ");
    fputs(book[x].hmerominia,fp);
    fprintf(fp," # ");
    fputs(book[x].timi,fp);
    fclose(fp);

 

Μετά στην ανάγνωση με ποιόν τρόπο θα μπορούσα να πάρω τα στοιχεία πίσω;

  • Απαντ. 40
  • Δημ.
  • Τελ. απάντηση
Δημοσ.

Αν και οι γνώσεις μου στη C είναι λίγο σκουριασμένες...

 

Οι 10 πίνακες τύπου char έχουν συγκεκριμένο μέγεθος; Αν ναι, θα πρέπει να βάλεις +1 στο μέγεθος τους για να συμπεριλάβεις κ τον χαρακτήρα /0 που δηλώνει το τέλος του string. Δηλαδή για το τηλέφωνο που είναι 10ψήφιο θα πρέπει να το αποθηκεύεις σε πίνακα χωρητικότητας 10+1=11 θέσεων. Χωρίς αυτό όταν προσπαθεις να τυπώσεις το τηλέφωνο, τυπώνονται τα πάντα μέχρι να βρει το /0 ή να πάρεις segmentation fault.

Δημοσ.
Αν και οι γνώσεις μου στη C είναι λίγο σκουριασμένες...

 

Οι 10 πίνακες τύπου char έχουν συγκεκριμένο μέγεθος; Αν ναι, θα πρέπει να βάλεις +1 στο μέγεθος τους για να συμπεριλάβεις κ τον χαρακτήρα /0 που δηλώνει το τέλος του string. Δηλαδή για το τηλέφωνο που είναι 10ψήφιο θα πρέπει να το αποθηκεύεις σε πίνακα χωρητικότητας 10+1=11 θέσεων. Χωρίς αυτό όταν προσπαθεις να τυπώσεις το τηλέφωνο, τυπώνονται τα πάντα μέχρι να βρει το /0 ή να πάρεις segmentation fault.

Ναι αυτό ήταν!

Ευχαριστώ πολύ για την παρατήρηση.

Είχα ξεχάσει το /0 :-(

:-D

 

---------- Προσθήκη στις 23:56 ---------- Προηγούμενο μήνυμα στις 23:46 ----------

 

Επίσης συνάντησα μία ακόμα ιδιοτροπία.

Ακόμα πιο περίεργο.

Το πρόγραμμα αυτό το έβγαλα από τη main και το έβαλα σε μία συνάρτηση void χωρίς παραμέτρους και χωρίς να επιστρέφει τίποτα.

Απλά θα παίρνει στοιχεία από το πληκτρολόγιο και θα τα περνάει στο αρχείο.

Στη main έχω μια switch

Όταν δοθεί κάποια σταθερά στη switch θα εκτελεστεί η συνάρτηση. Μόνο τότε.

Όταν όμως εκτελείται την ώρα που ζητάει όνομα εταιρίας και διεύθυνση

τα ζητάει ταυτόχρονα. δηλαδή με λίγα λόγια παρακάμπτει τη μία gets που έχω για ανάγνωση χαρακτήρων από το πληκτρολόγιο.

και στην οθόνη μου βγάζει:

>dose onoma etairias: ([color="Blue"]εδώ χάνουμε τη μια gets[/color]) dose dieuthinsi: ([color="blue"]εδώ περιμένει πληκτρολόγηση[/color]) 

Η συνάρτηση δουλεύει κανονικά εκτός της switch.

Δηλαδή αν την βάλω κάπου αλλού στο πρόγραμμα θα δουλέψει κανονικά.

Μόνο στη switch μέσα είδα αυτό το πρόβλημα.

Δημοσ.

Η σταθερά για τη switch την δίνεις από το πληκτρολόγιο; Με ποιά εντολή; Μάλλον δεν καταναλώνεται το '\n' που δίνεις για αυτή τη σταθερά κ το καταναλώνει η 1η gets.

Δημοσ.

Τώρα το αντίθετο πώς θα μπορούσε να γίνει;

Να πάρω τα στοιχεία από το αρχείο και να τα αποθηκεύσω στα structs.

Το πρόβλημα είναι οτι θα πρέπει να έχω πολλές τέτοιες σειρές με στοιχεία.

Σκέφτηκα νa ξεχωρίζω τους πίνακες με #, και κάθε φορά που βλέπει # να αλλάζει κάποιον δείκτη και να πηγαίνει στο επόμενο πίνακα του struct. Σταματάει όταν τελειώσει η γραμμή.

 

---------- Προσθήκη στις 00:26 ---------- Προηγούμενο μήνυμα στις 00:24 ----------

 

Η σταθερά για τη switch την δίνεις από το πληκτρολόγιο; Με ποιά εντολή; Μάλλον δεν καταναλώνεται το '\n' που δίνεις για αυτή τη σταθερά κ το καταναλώνει η 1η gets.

Ναι από το πληκτρολόγιο με scanf... τύπου int

Δημοσ.

Καλή ιδέα, κάθε γραμμή θα είναι ένα struct και κάθε γραμμή θα την κάνεις split με το # για να πάρεις τον κάθε πίνακα.

Δημοσ.
Καλή ιδέα, κάθε γραμμή θα είναι ένα struct και κάθε γραμμή θα την κάνεις split με το # για να πάρεις τον κάθε πίνακα.

Διαπιστώνω ένα πρόβλημα όπως στην αλλαγή των structs.

Το πως από έναν πίνακα θα μεταβεί στον επόμενο όταν βλέπει #.

Δημοσ.

@Giorgos3924 Εφοσον εχεις strcut με γνωστο μεγεθος, γιατι δε το γραφεις οπος ειναι;

δες ενα παραδειγμα (ειναι c++ αλλα με c style)

>#pragma pack(1)
struct foo
{
char a[10];
char b[10];
char c[10];
};
int _tmain(int argc, _TCHAR* argv[])
{
FILE *fp =fopen("test","wb");
foo f;
strcpy(f.a,"abcd");
strcpy(f.b,"1234");
strcpy(f.c,"!@$%");
fwrite(&f,sizeof(foo),1,fp);
fclose(fp);

fp = fopen("test","rb");
foo f1;
fread(&f1,sizeof(foo),1,fp);
printf("%s\n%s\n%s",f1.a,f1.b,f1.c);
fclose(fp);
getchar();

return 0;
}

Δημοσ.
Kάνε πριν από την πρώτη gets() ένα fflush(stdin)...

 

Βασικά καλό είναι να αποφεύγεται η χρήση της fflush(stdin).

int fflush(FILE *ostream);

 

ostream points to an output stream or an update stream in which the

most recent operation was not input, the fflush function causes any

unwritten data for that stream to be delivered to the host environment to

be written to the file; otherwise, the behavior is undefined.

http://faq.cprogramming.com/cgi-bin/smartfaq.cgi?answer=1052863818&id=1043284351

Μια πιθανή λύση είναι η εξής:

>int c; 
while ((c = getchar()) != EOF && c != '\n') ;

Δημοσ.

Εγώ το σκεφτόμουν αλλιώς.

Στο αρχείο:

>electronica # thesaloniki # 342415134 # 6900000000 # 12.33 # 12/02/2003 # 150E

Ξεκινάμε με:

>[color="blue"]do {[/color]
[color="Green"]ch=fgetc(fp);[/color]
[color="Red"]if (ch!='#')
metabliti[0].eteria[i]=ch;[/color] [color="blue"]
i++;}[/color]
[color="Blue"]while (ch!='#');[/color]

Μετά από εδώ θα πρέπει να αλλάζει το 2ο μέλος του strutct.

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

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

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

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