Sophoclis Δημοσ. 25 Νοεμβρίου 2011 Δημοσ. 25 Νοεμβρίου 2011 Γεία σας, έχω ενα αρχείο και 8ελω να παρω τις πληροφορίες και να τις βάλω σε μια δομή... Το προβλημα μου είναι ότι δεν δικαιούμαι να χρησιμοποιήσω συναρτήσεις της βιβλιοθήκης stdio.h όποτε πρεπει να χρησιμοποιήσω μόνο system calls, ετσι έχω προβλημα με την μνήμη και μου κτυπά segmentation fault .... Αν υπάρχει κάποιος να με βοηθήσει, τότε να ανεβάσω τον κώδικα μου μαζί με το αρχείο ....
παπι Δημοσ. 25 Νοεμβρίου 2011 Δημοσ. 25 Νοεμβρίου 2011 >#include <stdio.h> struct DOMH { int a,b; }; int main(int,char**) { struct DOMH domh; FILE *arxeio; int d; float f; char str[20]; domh.a = 1; domh.b = 4; arxeio = tmpfile(); //fread\fwrite fwrite(&domh,sizeof(struct DOMH),1,arxeio); fseek(arxeio,0,SEEK_SET); fread(&domh,sizeof(struct DOMH),1,arxeio); printf("a:%d b:%d",domh.a,domh.; fseek(arxeio,0,SEEK_SET); //fprintf/fscanf fprintf(arxeio,"%d %s %f",100,"hey",1.5e10); fseek(arxeio,0,SEEK_SET); fscanf(arxeio,"%d %s %f",&d,str,&f); printf("\n%d %s %f",d,str,f); fclose(arxeio); return 0; } Για τις συναρτησεις http://www.cplusplus.com/reference/clibrary/cstdio/
Sophoclis Δημοσ. 25 Νοεμβρίου 2011 Μέλος Δημοσ. 25 Νοεμβρίου 2011 Ευχαριστώ για την απάντηση αλλά όπως ανάφερα δεν μπορώ μου επιτρέπεται να χρησιμοποιήσω συναρτήσεις stdio.h !! αυτό είναι τα περιεχόμενα του αρχείου: 1. Distributed Systems 1234 Achieving Less Bugs with More FUN in CS601 63 1 2. Distributed Systems 5678 Distributed Systems for Dummies 85 1 3. College Life 9876 Surviving UCY 42 1 4. College Life 5432 How to avoid work 38 1 Και αυτός ο κώδικας μου: #include <stdio.h> //For I/O #include <unistd.h> #include <stdlib.h> #include <string.h> #include <strings.h> #include <fcntl.h> main() { char *filename="database.txt",c,*temp; int filefd,bytes,i,j,count; typedef struct{ char *ch; char *category; char *code; char *title; char *cost; char *stock; } book; int howManyBooks=4; book *books; //copy database.txt to shared memory if ((filefd = open(filename, O_RDONLY|O_CREAT, 0600)) < 0 ) error("ERROR open file"); lseek(filefd,0,SEEK_SET); i=0; count=0; do { j=0; do { bytes=read(filefd,&c,1); temp[j]=c; j++; if (c == '\t') { count++; switch (count) { case 1: strcpy(books.ch,temp); break; case 2: strcpy(books.category,temp); break; case 3: strcpy(books.code,temp); break; case 4: strcpy(books.title,temp); break; case 5: strcpy(books.cost,temp); break; case 6: strcpy(books.stock,temp); break; }//end of switch (count) }//end of if (c == '\t') j=0; }while (c != '\n'); i++; count=0; }while (bytes > 0); for (i=0; i<howManyBooks; i++) { printf("%s Category:%s Code:%s Title:%s Price:%s Stock:%s\n",books.ch, books.category, books.code, books.title, books.cost, books.stock); } close(filefd); } Στο αρχείο τα κενά αντίς space είναι tab !! επειδή το πρόβλημα είναι segmentation fault ,λογικά το λάθος βρίσκεται while (c != '\n'); i }while (bytes > 0);
παπι Δημοσ. 25 Νοεμβρίου 2011 Δημοσ. 25 Νοεμβρίου 2011 >typedef struct{char *ch;char *category;char *code;char *title;char *cost;char *stock;} book; αυτα δειχνουν στο γαμο του καραγκιοζη. Αλλαξε τα με char ch[100] char category[100] etc..
Sophoclis Δημοσ. 25 Νοεμβρίου 2011 Μέλος Δημοσ. 25 Νοεμβρίου 2011 χεχεχε ωραίος με έκανες και γέλασα οκ το δοκιμάζω και ενημερώνω... >typedef struct{char *ch;char *category;char *code;char *title;char *cost;char *stock;} book; αυτα δειχνουν στο γαμο του καραγκιοζη. Αλλαξε τα με char ch[100] char category[100] etc.. τα όρισα [100] , το ίδιο έκανα και στο temp[100] και στο book books[4] διορθώσαμε το segmentation fault, ευχαριστώ να'σε καλά! αλλά δεν περνανε τα περιεχόμενα στην δομή... θα το ψάξω καλύτερα!
Sophoclis Δημοσ. 25 Νοεμβρίου 2011 Μέλος Δημοσ. 25 Νοεμβρίου 2011 sscanf????? θα προσπαθήσω να τυπώνε μετα απο κάθε strcpy ..για να δούμε!! sscanf τιποτε τα ίδια, από το καιρό που έχει να χρησιμοποιήσω C ....δεν με βλέπω να βγάζω άκρη πρόσθεσα και αυτό bytes=read(filefd,&c,1); temp[j]=c; printf("%c",temp[j]); και τα τυπώνει σωστά!! θα πηγαίνει λάθος με το strcpy ?
παπι Δημοσ. 25 Νοεμβρίου 2011 Δημοσ. 25 Νοεμβρίου 2011 θα πηγαίνει λάθος με το strcpy ? οχι, απλα το books δειχνει και αυτο στο γαμο του καραγκιοζη αλλαξετο απο book *books σε book books[10]
Sophoclis Δημοσ. 25 Νοεμβρίου 2011 Μέλος Δημοσ. 25 Νοεμβρίου 2011 σου το ανάφερα φίλε μου, όταν μου είπες για τα άλλα το άλλαξα και αυτό σε book books[4];
migf1 Δημοσ. 26 Νοεμβρίου 2011 Δημοσ. 26 Νοεμβρίου 2011 (επεξεργασμένο) Για να είμαι ειλικρινής βαριέμαι να κάτσω να διαβάζω τώρα την τεκμηρίωση των system calls (που παίζει να έχω να τα χρησιμοποιήσω πάνω από 10 χρόνια!) την βασική ιδέα στην περιέγραψε ο παπι... από την στιγμή που έχεις την read() που διαβάζει bytes από αρχείο, την καλείς με sizeof(δομής), sizeof(πεδίο δομής) ή sizeof(string) ανάλογα την υλοποίηση που θα φτιάξεις. Από τη στιγμή που το κάθε πεδίο έχει μεταβλητό μέγεθος μέσα στο αρχείο και εφόσον δεν χρησιμοποιείται κάποιο είδους padding στο κάθε πεδίο, η 1η σκέψη που κάνω είναι να διαβάζεις την κάθε γραμμή ξεχωριστά χαρακτήρα προς χαρακτήρα με την read() μέχρι να βρες αλλαγή γραμμής ( '/n' ή '/r' '/n', ανάλογα αν μιλάμε για αρχείο κειμένου σε μορφή unix ή windows) και να την αποθηκεύεις σε ένα string. Κατόπιν να φτιάξεις έναν string-tokenizer που θα την σπάει σε tokens (ανά κενό διάστημα) και θα τα αποθηκεύει σε ένα array of strings. Εφόσον η σειρά των tokens είναι fixed στο αρχείο, μπορείς να επεξεργαστείς το array of tokens για να πάρεις τα πεδία που θέλεις. π.χ... > /* 1. Distributed Systems 1234 Achieving Less Bugs with More FUN in CS601 63 1 2. Distributed Systems 5678 Distributed Systems for Dummies 85 1 3. College Life 9876 Surviving UCY 42 1 4. College Life 5432 How to avoid work 38 1 */ #define MAXBOOKS 4 #define TOKENSIZE 255+1 #define CATEGORYSIZE (2 * (TOKENSIZE-1)) + 2 + 1 /* 2 spaces between tokens + '\0' */ #define TITLESIZE (20 * (TOKENSIZE-1)) + 20 + 1 /* 20 spaces between tokens + '\0' */ #define MAXTOKENS 100 #define MINTOKENS 7 /* ------------------------------------------------------- */ char *readstr( int fdesc, char str[], size_t strsize ) { char *cp = str; for (; --strsize && *cp != '\n'; cp++) if ( read( fdesc, cp, sizeof(char) ) != sizeof(char) ) { /* read failed, handle error here */ break; } *cp = '\0'; return str; } /* ------------------------------------------------------- */ int tokenizestr( char *str, int ntokens, tokens[ MAXTOKENS ][ TOKENSIZE ], char *delimiters ) { /* * Tokenize str to up to ntokens tokens, according to delimeters, * store the resulting tokens into the array tokens[][], and return * the 0-based index of the last token in the array */ } /* ------------------------------------------------------- */ int main( void ) { /* !!! at least MINTOKENS tokens !!! */ struct book { char ch[ TOKENSIZE ]; /* 1 token */ char category[ CATEGORYSIZE ]; /* 2 tokens */ int code; /* 1 token */ char title[ TITLESIZE ]; /* any # of tokens, up to 20 */ int cost; /* 1 token */ int stock; /* 1 token */ } books[ MAXBOOKS ] = { {"", "", -1, "", -1, -1} }; int i, fdesc = -1, itoklast = 0; char str[ 1023+1] = {'\0'}; char tokens[ MAXTOKENS ][ TOKENSIZE ] = { "" }; fdesc = open( filename, ... ); if ( -1 == fdesc ) /* file open error, handle the error here */ i = 0; while ( /* not eof - δεν θυμάμαι πως ελέγχεται αυτό με system calls */ ) { int j=0; readstr( fdesc, str, 1023+1); itoklast = tokenizestr( str, MAXTOKENS, tokens, " "); if ( itoklast < MINTOKENS-1 ) /* η readtsr() βρήκε στη γραμμή λιγότερα tokens από τα ελαχιστα απαιτούμενα, handle the error here */ /* .ch (1 token) */ strncpy( books[0].ch, tokens[0], TOKENSIZE-1 ); /* .category (2 tokens) */ strncat( books[i].category, tokens[1], CATEGORYSIZE-1 ); strncat( books[i].category, " ", 1); strncat( books[i].category, tokens[2], CATEGORYSIZE-TOKENSIZE) ); /* .code (1 token) */ books[i].code = atoi( tokens[3] ); /* .title = all tokens between 4 and last-2 (inclusive) with spaces between*/ for (j=4; j < itoklast-1; j++) { strncat( books[i].title, tokens[j], TITLESIZE - (j-3)*TOKENSIZE - 1); strcat( books[i].title, " "); } books[i].title[ strlen(books[i].title)-1 ] = '\0'; /* remove last space */ /* .cost (1 token) */ books[i].cost = atoi( tokens[ j /* or itoklast-1 */ ];/* προτελευταίο token */ /* .stock (1 token) */ books[i].stock = atoi( tokens[ ++j /* or itoklast */ ];/* τελευταίο token */ i++; } close( fdesc ); /* print our book data structures */ for (i=0; i < MAXBOOKS; i++) printf( "%s %s %d %s %d %d\n", books[i].ch, books[i].category, books[i].code, books[i].title, books[i].cost, books[i].stock ); return 0; } ΥΓ. Btw, η sscanf() είναι στο stdio.h Είχα κάνει... λαλακία στον κώδικα με τις κλήσεις των readstr() και tokenizestr()... το διόρθωσα. Ενδεχομένως να υπάρχουν κι άλλα λάθη, δεν τον έχω δοκιμάσει! Επεξ/σία 27 Νοεμβρίου 2011 από migf1
Sophoclis Δημοσ. 26 Νοεμβρίου 2011 Μέλος Δημοσ. 26 Νοεμβρίου 2011 (επεξεργασμένο) migf1 Σε ευχαριστώ για την βοήθεια σου!! με πιέζει ο χρόνος για έχει πολλή δρόμο ακόμη το project , θα κοιτάξω την λύση σου, για να μάθω και 5 πράγματα παραπάνω!! Εδώ είναι η δική μου λύση , όπου λύθηκε το πρόβλημα, χάρη στην βοήθεια σας!!! > #include <sys/types.h> //For sockets, System V IPC #include <sys/socket.h> //For sockets #include <netinet/in.h> //For Internet sockets #include <netdb.h> //For gethostbyaddr #include <sys/ipc.h> //For System V IPC #include <sys/shm.h> //For shared memory #include <sys/sem.h> //For semaphores #include <stdio.h> //For I/O #include <unistd.h> #include <stdlib.h> #include <sys/wait.h> #include <signal.h> #include <string.h> #include <strings.h> #include <fcntl.h> #include <time.h> main() { char *filename="database.txt",c,temp[100]; int filefd,bytes,i,j,count; typedef struct{ char ch[100]; char category[100]; char code[100]; char title[100]; char cost[100]; char stock[100]; } book; int howManyBooks; book books[4]; //copy database.txt to shared memory if ((filefd = open(filename, O_RDONLY|O_CREAT, 0600)) < 0 ) error("ERROR open file"); printf("OPEN FILE CORRECT\n"); lseek(filefd,0,SEEK_SET); i=0; count=0; do { j=0; do { bytes=read(filefd,&c,1); temp[j]=c; //printf("%c",temp[j]); j++; if (c == '\t') { count++; switch (count) { case 1: temp[j]='\0'; strcpy(books[i].ch,temp); j=0; break; case 2: temp[j]='\0'; strcpy(books[i].category,temp); j=0; break; case 3: temp[j]='\0'; strcpy(books[i].code,temp); j=0; break; case 4: temp[j]='\0'; strcpy(books[i].title,temp); j=0; break; case 5: temp[j]='\0'; strcpy(books[i].cost,temp); j=0; break; }//end of switch (count) }//end of if (c == '\t') }while (c != '\n'); temp[j-1]='\0'; strcpy(books[i].stock,temp); j=0; i++; count=0; }while (bytes > 0); howManyBooks=i-1; for (i=0; i<howManyBooks; i++) { printf("%s Category:%s Code:%s Title:%s Price:%s Stock:%s\n",books[i].ch, books[i].category, books[i].code, books[i].title, books[i].cost, books[i].stock); } close(filefd); } Επεξ/σία 27 Νοεμβρίου 2011 από Sophoclis
GKNSB Δημοσ. 26 Νοεμβρίου 2011 Δημοσ. 26 Νοεμβρίου 2011 Βάλ'τα και σε [ code][ /code] να διαβάζεται πιο ανθρώπινα να σε χαρώ
migf1 Δημοσ. 26 Νοεμβρίου 2011 Δημοσ. 26 Νοεμβρίου 2011 Εφόσον τα κατάφερες, όλα καλά ΥΓ1. Κάνε edit τα ποστ σου και βάλε τον κώδικα μέσα σε [ code] [/ code] (χωρίς τα κενά) για να μπορούμε να τον διαβάζουμε. ΥΓ2. Με πρόλαβε ο GKNSB!
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα