Thread: need help about array of struct

  1. #1
    Registered User
    Join Date
    Nov 2009
    Location
    Italy
    Posts
    65

    need help about array of struct

    Hi all, i need to understand how to solve the following exercise, I have a structure:
    Code:
    #define FRAMESIZE 17		// carframe size
    
    typedef struct {
    	char *name;         // owner name
    	char *surname;   // owner surname
    	char carframe[FRAMESIZE];     // carframe number(alphanumeric)
    	struct {
    		int d;		// day
    		int m;		// month
    		int y;		// year
    	} matr;						// matriculation date
    } Vehicle;
    I have to implement a function Vehicle *buildarchive(char *text, int *n) that creates a dynamically allocated array of struct Vehicle whose values are contained into the string text and that returns in *p the number of struct, each string is divided by rows in order to contain datas of each vehicle, every row has the following format: N;S;F;D;M;Y where N is the owner's name, S the surname etc.. and terminates with the character '\n', so if the text is:
    Code:
    Mario;Dell'Olio;ABCD1234567899GHT;12;1;2004
    Laura;Di Carlo;ABBB0987654321HGT;3;10;1999
    Maria Luisa;Crociani Sforza Pallavicini;NNNN1234567890BFB;25;11;2006	
    Giorgio;Verdoni;AAAA09876FFT54321;10;10;2009
    the function creates the following array, and return in *p the value 4:
    Code:
    [0] = {"Mario", "Dell'Olio", ABCD1234567890GHT, {12, 1, 2004}}
    [1] = {"Laura", "Di Carlo", ABBB0987654321HGT, {3,10,1999}}
    etc till [3] = ...
    now what i did till now is basically just printing on screen each row:
    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #define FRAMESIZE 17		// carframe size
    
    typedef struct {
    	char *name;
    	char *surname;
    	char carframe[FRAMESIZE];
    	struct {
    		int d;		// day
    		int m;		// month
    		int y;		// year
    	} matr;						// matriculation date
    } Vehicle;
    
    Vehicle *buildarchive(char *text, int *n);
    int main()
    {
    	char string[] = {"Mario;Dell'Olio;ABCD1234567899GHT;12;1;2004\n"
    						 "Laura;Di Carlo;ABBB0987654321HGT;3;10;1999\n"
    						 "Maria Luisa;Crociani Sforza Pallavicini;NNNN1234567890BFB;25;11;2006\n"			
    						 "Giorgio;Verdoni;AAAA09876FFT54321;10;10;2009\n"
    						 };
    
    	int *p;
    	
    	buildarchive(string, p);
    
    	return 0;	
    }
    Vehicle *buildarchive(char *text, int *n)
    {
    	int count = 0, i;
    	char *text_temp;
    	char *text_tmp;
    	text_temp = text;
    	text_tmp = text;
    	
    	/* counts rows */
    	while(*text_tmp != '\0') {
    		if(*text_tmp == '\n') {
    			count++;
    		}
    		*text_tmp++;
    	}
    	
    	Vehicle *array = (Vehicle*)malloc(count * sizeof(Vehicle));
    	
    	while(*text != '\0') {	  		// iterates till the string reaches the '\0' character
    		while((*text_temp != ';')&&(*text_temp != '\n')) {		
    			printf("%c", *text_temp);
    			*text_temp++;			
    		}			
    		text = text_temp;		
    		if(*text == '\n') {
    			printf("\n");
    		}
    		*text++;
    		text_temp = text;
    	}
    	printf("\nsentences = %d (counter)\n", count);
    }
    the counter counts the number of rows so that i could create an array of Vehicle but im stuck trying to understand how to put each information into this array, any suggestion? thanks ^^

  2. #2
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Well, you would access the individual elements and members like this:
    Code:
    array[0].matr.d = 31;
    Obviously, the "name" member will need to be malloc'd memory before use.

    BTW, you do not need to typecast void* in C:
    Code:
    Vehicle *array = (Vehicle*)malloc(count * sizeof(Vehicle));
    This is fine:

    Vehicle *array = malloc(count * sizeof(Vehicle));
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  3. #3
    Registered User
    Join Date
    Nov 2009
    Location
    Italy
    Posts
    65
    I still have a problem.. now i'm trying to save each string so that i will be able to put them into the array, but i got an error with realloc: invalid next size error
    Code:
    char *text_temp;
    	char *text_tmp;
    	char *hold;
    	text_tmp = text_archive;  // text is the original string
    	text_temp = text_archive;
    	
    	char *s1 = malloc(50*sizeof(char));
    	char *ptr = malloc(25*sizeof(char));
    	int offset = 0;
    	
    	while(*text_tmp != '\n') {
    		hold = text_temp;
    		while(*text_temp != ';') {
    			offset++;
    			*text_temp++;
    		}
    		ptr = strncpy(s1, hold, offset);    // strncpy saves each string 
    		printf("%s\n", ptr);
    		ptr = realloc(ptr, offset+1);
    		offset = 0;
    		*text_temp++;
    		*text_tmp++;
    	}
    }
    it does the first 3 iterations and than shows the error, i want to keep each substring of the string text_archive, each one separated by the ';' character.. i must have done something wrong with realloc() but realloc(ptr, offset+1) seems fine to me..any suggestion on why i get the error?
    Last edited by rob90; 12-23-2009 at 06:57 AM.

  4. #4
    Registered User
    Join Date
    Mar 2009
    Posts
    48
    I think it should be :
    Code:
    ptr = realloc(ptr, (offset+1) * sizeof(*ptr));
    Haven't tested it though.
    Last edited by zalezog; 12-23-2009 at 01:07 PM.

  5. #5
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    How Do You Add Onto Dynamic Memory After You've Already Malloc-ed It?

    If realloc fails, you will lose whatever ptr contains. Consider storing the return value elsewhere first and checking for validity before assigning it to ptr.


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

  6. #6
    Registered User
    Join Date
    Nov 2009
    Location
    Italy
    Posts
    65
    I solved my problem, the function creates the array well and everything works fine but I still dont understand how to return a pointer to the number of structures used, the function Vehicle *buildarchive(char *text, int *n) should return n which in my case is 4 because the number of structures is equal to the number of rows of the string, so i made n = &count, which is the number of rows, but if I return that value i got random numbers, any ideas?

  7. #7
    Registered User
    Join Date
    Nov 2009
    Location
    Italy
    Posts
    65
    if I do a print of n inside the function it shows that its value is right, however i still cant understand how to return its value since the function should return a pointer to Vehicle..

  8. #8
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by rob90 View Post
    I solved my problem, the function creates the array well and everything works fine but I still dont understand how to return a pointer to the number of structures used, the function Vehicle *buildarchive(char *text, int *n) should return n which in my case is 4 because the number of structures is equal to the number of rows of the string, so i made n = &count, which is the number of rows, but if I return that value i got random numbers, any ideas?
    No need to return n if you have passed a pointer to count in buildarchive().
    Putting it indirectly, n is a pointer to count while *n is the same as count.

  9. #9
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by rob90 View Post
    if I do a print of n inside the function it shows that its value is right, however i still cant understand how to return its value since the function should return a pointer to Vehicle..
    Are you printing n or *n? Since n is the location of count while *n is count.
    Returning from buildarchive(), count in the calling function will be equal to *n.
    Last edited by itCbitC; 12-26-2009 at 06:41 PM.

  10. #10
    Registered User
    Join Date
    Nov 2009
    Location
    Italy
    Posts
    65
    I'm printing *n, its value is right, but i dont need to print it inside the function, i need to return it, however this function Vehicle *buildarchive(char *text, int *n) should return a pointer to Vehicle while *n is a pointer to int, that's what i don't understand..

  11. #11
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by rob90 View Post
    I'm printing *n, its value is right, but i dont need to print it inside the function, i need to return it, however this function Vehicle *buildarchive(char *text, int *n) should return a pointer to Vehicle while *n is a pointer to int, that's what i don't understand..
    Function Vehicle *buildarchive(char *text, int *n) explicitly returns Vehicle *, and implicitly returns *n.
    You are not explicitly returning *n, but count in the calling function acquires that value rather indirectly.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Converting from C to C++
    By Taka in forum C++ Programming
    Replies: 5
    Last Post: 04-08-2009, 02:16 AM
  2. Replies: 1
    Last Post: 12-03-2008, 03:10 AM
  3. Fixing my program
    By Mcwaffle in forum C Programming
    Replies: 5
    Last Post: 11-05-2008, 03:55 AM
  4. Array of struct pointers - Losing my mind
    By drucillica in forum C Programming
    Replies: 5
    Last Post: 11-12-2005, 11:50 PM
  5. towers of hanoi problem
    By aik_21 in forum C Programming
    Replies: 1
    Last Post: 10-02-2004, 01:34 PM