Thread: reading structure from file..??

  1. #1
    Registered User
    Join Date
    Dec 2001
    Posts
    25

    Question reading/scanning array of structure ??

    Hi,

    I ve array of structure..

    Code:
     
    struct record
    {
    	int  key;
    	char *word;
    } Record;
    my 1st task is to read the file (ex: struct.txt) which contain such a data....

    Code:
    24109	vinegar
    16554	papacy
    12127	integrity
    9429	gale
    13154	Laramie
    21442	squeak
    3385	buss
    6875	disturbance
    16119	Olaf
    446	afterimage
    14399	Maxwellian
    13588	lisle
    6109	Deanna
    16130	oleomargarine
    13828	luck
    15314	muscular
    6936	DOD
    5930	cyclic
    20096	sector
    20975	snook
    7189	drudge
    what i want to do is scan the integer and put it in the int key and scan the word, and put it in char *word, after done with one structure then proceed to second structure (second array)...

    this is all what i ve done at the moment:

    Code:
     
    /* This is the function to open 'fname' in the required mode, if fname cannot be opened, then print error and 'exit-fail' */
    
    FILE *open_file( char *progname, char *fname, const char *mode )
    {
    
    	FILE *fp;
    
    	fp = fopen( fname, mode );
    	if( fp == NULL )
    	{
    	   fprintf( stderr, "%s: ERROR: File \"%s\" not opened; Progname execution" 
    				  " terminated.\n", progname, fname );
    	   exit( EXIT_FAILURE );
    	}
    
    	return fp;
    
    }
    	
    /* This function read word from textfile (input), and then store the word first into 'buffer', then stored it to dynamic memory, then return the wordpointer, otherwise if the end of the reached the return NULL. */
    
    char *get_word( FILE *fp )
    {
    	
    	char *wordptr;
    	char buffer[WORDSIZE];
    	
    	if( ( fscanf( fp, "%s", buffer ) ) == 1 )
    	{
    		wordptr = create_word_array( strlen( buffer ) );
    		strcpy( wordptr, buffer );
    
    		return wordptr;
    	}
    	else
    	{
    		return NULL;
    	}
    
    }
    
    /* This function allocate memory for (len+1) * size of chars, then return the address of that dynamically allocated memory. If memory allocation fail, then 'exit-fail'. */
    
    char *create_word_array( int len )
    {
    
    	char *ptr;
    
    	ptr = ( char* ) malloc( ( len + 1 ) * sizeof( char ) );
    	if( ptr == NULL )
    	{
    		fprintf( stderr, "Memory allocation failed; program terminated.\n" );
    		exit( EXIT_FAILURE );
    	}
    
    	return ptr;
    
    }
    however I dont know how to read the int and then continue read the word, then proceed to next structure...i am thinking of doing it this way, but it's not working *_* (this is not scanning though, i coz i dont know what scanning method I can use)

    Code:
    void print_record( File *fp ) 
    {
    
        int i;
    
        for ( i = 0 ; i < ASIZE ; i++ )
    	{
    		printf( "%d\t%s\n", data[i].key, data[i].word ); 
        }
        
    	printf( "\n" );
    
    	return;
    
    }
    any help will be appreciated...

    thanks.

    CyC|OpS
    Last edited by CyC|OpS; 09-07-2002 at 06:05 AM.

  2. #2
    Registered User
    Join Date
    Dec 2001
    Posts
    25
    um...nobody can help issit?
    or u guys dont understand what is my question?

  3. #3
    Registered User
    Join Date
    Apr 2009
    Posts
    2

    a possible solution

    In a word here is what I did:

    build a single string from the input file, parse the string and allocate dynamically an array of struct...
    I checked with valgrind for any possible memory leak and it didn"r raise any !

    In the following, fle.ini is the text file you copy/paste.

    There is still some work to do, convert the key (char* format) to an int value. See the line that starts with : array[i].key = 1.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    typedef struct {
    	int key;
    	char *word;
    } record;
    
    void free_records_in_memory (record *array, int pos) {
    	for ( ; pos >= 1 ; pos-- )
    		free(array[pos-1].word);
    	free(array);
    }
    
    void show_records_in_memory(record *array, int size) {
    	record *ptr = NULL;
    	for (ptr = array; size != 0; size--, ptr++)
    		printf("key is [%d] and associated word is [%s]\n", ptr->key, ptr->word);
    
    }
    
    char *bufferised_file_into_a_single_string ( const char *filepath ) {
    	char *line = NULL;
    	int length = 0;
    	FILE *f = NULL;
    
    	if (NULL == (f = fopen(filepath, "rb"))) {
    		perror("Failed to open file to load ");
    		return NULL;
    	}
    
    	fseek(f, 0, SEEK_END );
    	length = ftell(f);
    	fseek(f, 0, SEEK_SET );
    
    	if (NULL == (line = malloc(sizeof(char) * (length + 1)))) {
    		perror("Can't allocate room for buffering the whole file ");
    		return NULL;
    	}
    
    	if (1 != (fread(line, length, 1, f))) {
    		perror("Failed to read data ");
    		free ( line );
    		return ( line = NULL );
    	}
    
    	line[length + 1] = 0;
    
    	fclose(f);
    
    	return line;
    }
    
    record *parse_line_into_array_of_structs(char *line, int *records_cnt) {
    
    	char *p = NULL, *q = NULL, *r = NULL;
    	record *array = NULL;
    	int i = 0;
    
    	for (p = line, *records_cnt = 0; *p;) {
    		if (*p++ == '\n')
    			(*records_cnt)++;
    	}
    
    	if (NULL == (array = calloc((*records_cnt), sizeof(record)))) {
    		perror("Can't allocate room for holding the whole file ");
    		return NULL;
    	}
    
    	for (q = line; NULL != (p = strchr(q, '\n')); i++, q = p + 1) {
    		r = q;
    		while (isdigit (*r))
    			r++;
    		array[i].key = 1;
    		while (*r == '\t' || *r == ' ')
    			r++;
    		array[i].word = malloc(sizeof(char) * (p - r + 1));
    		if (NULL == array[i].word) {
    			perror("Can't allocate room for word ");
    			free ( line );
    			free_records_in_memory ( array, i );
    			return (array = NULL);
    		}
    		memcpy(array[i].word, r, p - r);
    		(array[i].word)[p - r] = 0;
    	}
    
    	free(line);
    
    	return array;
    }
    
    int main() {
    	const char *path = "/home/emma/src/file.ini";
    	int counter = 0;
    
    	record *array_of_structs = NULL;
    
    	if (NULL == (array_of_structs = parse_line_into_array_of_structs( bufferised_file_into_a_single_string ( path ), &counter ) )) {
    		perror("Cannot load file into array ");
    		return 1;
    	}
    
    	show_records_in_memory(array_of_structs, counter);
    
    	free_records_in_memory(array_of_structs, counter);
    
    	return 0;
    }

  4. #4
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    You've already got a get_word, make a get_number. Change that %s to a %d, and store it in an int which you return instead of allocating a word/string.


    Quzah.
    Hope is the first step on the road to disappointment.

  5. #5
    Registered User
    Join Date
    Apr 2009
    Posts
    2
    In the code I posted, the statement
    line[length+1] = 0;
    is erroneous since length already takes into account the null character that
    ends-up the string.
    The correct statement to use is
    line[length] = 0;

  6. #6
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    6.5 year bump, wow!
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Newbie homework help
    By fossage in forum C Programming
    Replies: 3
    Last Post: 04-30-2009, 04:27 PM
  2. Can we have vector of vector?
    By ketu1 in forum C++ Programming
    Replies: 24
    Last Post: 01-03-2008, 05:02 AM
  3. Reading a file into a structure array
    By RazielX in forum C Programming
    Replies: 3
    Last Post: 05-02-2004, 09:30 AM
  4. Reading from file into structs..
    By dankas in forum C Programming
    Replies: 14
    Last Post: 10-16-2002, 10:33 PM
  5. simulate Grep command in Unix using C
    By laxmi in forum C Programming
    Replies: 6
    Last Post: 05-10-2002, 04:10 PM