Thread: questions about structures passing through functions

  1. #1
    Registered User
    Join Date
    Mar 2009
    Posts
    2

    questions about structures passing through functions

    I'm having this weird error when I pass in a structure array to a function to read it from file, but it keeps giving wrong output.

    Code:
    void process(int command, char *argc[])
    {
    	struct Contact contact[CONTACTSIZE];
    	int size = readSaved(contact);
    
    	printf("%s %s %s %s\n", contact[0].first, contact[0].last, contact[0].home, contact[0].cell);
    	
    	if(command == 1 || command == 2)
    		search(command, argc[2], contact, size);
    	else if(command == 3)
    	{
    		delete(argc[2], argc[3], contact, size);
    		size--;
    		Save(contact, size);
    	}
    	else 
    	{
    		add(command, argc[2], argc[3], argc[4], contact, size);
    		size++;
    		Save(contact, size);
    	}
    }
    Code:
    int readSaved(struct Contact contact[])
    {
    	FILE *fp;
    	int max = 2*NAMELENGTH + 2*PHONELENGTH;
    	char line[max],  *token;
    	int i = 0;
    
    	if((fp = fopen(FILENAME, "r")) != NULL)
    	{
    		while(fgets(line,max, fp) != NULL)
    		{
    			token = strtok(line, " ");
    			contact[i].first = token;
    
    			token = strtok(NULL, " ");
    			contact[i].last = token;
    			
    			token = strtok(NULL, " ");
    			contact[i].home = token;
    			
    			token = strtok(NULL, "\n");
    			contact[i].cell = token;
    
    			i++;
    		}
    		fclose(fp);
    	}
    
    	return i;
    }
    the output should be something like this: Tom Johnson 333-444-5555 111-222-3333
    but it keeps giving me this: space space space space.
    this is bothering me for a long time and I cannot find where went wrong??
    Can I get some help on this?
    thanks

  2. #2
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    The problem lies in how strtok() works. The strtok() function returns pointers into the string it's tokenizing. That is, it doesn't create new strings for you. So what you're doing is simply copying the pointer it's giving you into your array. Neither you nor strtok() is copying actual strings: just pointers.

    Two issues with your code thus emerge. First: each iteration of the loop you overwrite the string that was tokenized the previous time. Since your tokens are pointers into that memory area, they now point to various locations inside of the newly read string. Each token returned by strtok() is a pointer into your array called "line", and you keep changing that array. The way to get around this is to copy strings. In your case, since your struct members are pointers, you'd do something like:
    Code:
    contact[i].first = malloc(strlen(token) + 1);
    if(contact[i].first == NULL) /* uh oh ... */
    strcpy(contact[i].first, token);
    You can also make your struct members arrays, but then you'd have to worry about what happens if a token is too long for the array (and strncpy(), by itself, is not the answer--that function is a bit dangerous).

    The next problem actually will disappear when you fix your first problem, but I think is worth mentioning. Your "line" array is local to the function. That means that any pointers to it become invalid as soon as the function returns. Since your struct members now point inside that array, they are unusable after the function returns. No problem, though, if you allocate memory with malloc(), or use arrays in your struct.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Passing functions between files
    By Duskan in forum C Programming
    Replies: 9
    Last Post: 04-17-2007, 07:44 AM
  2. Passing arrays of pointers into functions
    By ashley in forum C Programming
    Replies: 5
    Last Post: 01-13-2007, 06:48 PM
  3. Replies: 6
    Last Post: 05-06-2003, 03:08 PM
  4. passing array structures to functions
    By lukejack in forum C Programming
    Replies: 2
    Last Post: 04-08-2003, 02:17 PM
  5. passing functions with variable
    By itld in forum C++ Programming
    Replies: 1
    Last Post: 10-30-2001, 11:43 PM