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

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

Δημοσ.

Γεία σας,

 

έχω ενα αρχείο και 8ελω να παρω τις πληροφορίες και να τις βάλω σε μια δομή... Το προβλημα μου είναι ότι δεν δικαιούμαι να χρησιμοποιήσω συναρτήσεις της βιβλιοθήκης stdio.h όποτε πρεπει να χρησιμοποιήσω μόνο system calls, ετσι έχω προβλημα με την μνήμη και μου κτυπά segmentation fault ....

 

Αν υπάρχει κάποιος να με βοηθήσει, τότε να ανεβάσω τον κώδικα μου μαζί με το αρχείο ....

Δημοσ.

>#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/

Δημοσ.

Ευχαριστώ για την απάντηση αλλά όπως ανάφερα δεν μπορώ μου επιτρέπεται να χρησιμοποιήσω συναρτήσεις 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);

Δημοσ.

>typedef struct{char *ch;char *category;char *code;char *title;char *cost;char *stock;} book;

αυτα δειχνουν στο γαμο του καραγκιοζη. Αλλαξε τα με char ch[100] char category[100] etc..

Δημοσ.

χεχεχε ωραίος με έκανες και γέλασα :-D

οκ το δοκιμάζω και ενημερώνω...

 

>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, ευχαριστώ να'σε καλά!

 

αλλά δεν περνανε τα περιεχόμενα στην δομή... θα το ψάξω καλύτερα!

Δημοσ.

sscanf?????

 

θα προσπαθήσω να τυπώνε μετα απο κάθε strcpy ..για να δούμε!!

 

sscanf happy.gif

 

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

 

πρόσθεσα και αυτό

bytes=read(filefd,&c,1);

temp[j]=c;

printf("%c",temp[j]);

 

και τα τυπώνει σωστά!!

 

θα πηγαίνει λάθος με το strcpy ?

Δημοσ.

 

 

θα πηγαίνει λάθος με το strcpy ?

 

οχι, απλα το books δειχνει και αυτο στο γαμο του καραγκιοζη grin.png αλλαξετο απο book *books σε book books[10]

Δημοσ. (επεξεργασμένο)

Για να είμαι ειλικρινής βαριέμαι να κάτσω να διαβάζω τώρα την τεκμηρίωση των 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()... το διόρθωσα. Ενδεχομένως να υπάρχουν κι άλλα λάθη, δεν τον έχω δοκιμάσει!

Επεξ/σία από migf1
Δημοσ. (επεξεργασμένο)

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);
}

Επεξ/σία από Sophoclis
Δημοσ.

Εφόσον τα κατάφερες, όλα καλά :)

 

ΥΓ1. Κάνε edit τα ποστ σου και βάλε τον κώδικα μέσα σε [ code] [/ code] (χωρίς τα κενά) για να μπορούμε να τον διαβάζουμε.

 

ΥΓ2. Με πρόλαβε ο GKNSB!

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...