views:

35

answers:

3

I am reading a line from a file containing the names of people, first line contains names of males, and seconds line contains names of females. Then I want to store these names in two arrays, one for males, one for females, however when I print them I get weird things. I'm not sure if I am not reading them correctly, or printing them incorrectly

    char line[100];      //holds line read
    char *item;         //item in a line
    char *item2;
    int participants = 5;   //number of people in the event

            char* maleNames[participants];
            char* femaleNames[participants];

            fgets(line, 255, file);
            int i;
            item = strtok(line, " ");
            for(i=0; i<participants; i++)
            {
                maleNames[i] = item;  
                item = strtok(NULL, " ");


               }

        //read female names now
        fgets(line, 1024, file);
        item2 = strtok(line, " ");
        for(i=0; i<participants; i++)
        {
            femaleNames[i] = item2;
            item2 = strtok(NULL, " ");
        }

These lines are read

John Jeffrey Adam Mark Peter
Jenny Alice Sally Wendy Amanda

However when I print them out like this:

        for(i=0;i<participants;i++)
        {
            printf("%s %s\n", maleNames[i], femaleNames[i]);
        }

I get something so different:

Jenny Jenny
 Alice
ally Sally
Wendy Wendy
 Amanda

Note: if I print the names of males right after they're read before reading the female names, then they are printed correctly

+1  A: 

Not paying attention to other problems (like the size, 255 and 1024, you pass to fgets when your buffer is only 100 characters long), this problem most likely comes from the fact that you are using the same buffer, char line[100], for both calls to fgets(). Strtok returns a pointer to a character in the line buffer, so when you store in "line" the female names, all these pointers, relative to line when line contained the male names, are now invalid. Try storing the female line in other buffer, it should work.

EDIT: Sorry if the "not paying attention..." sounds discouraing. Nothing more far away from my intention. Everyone make mistakes everytime, specially when learning. I wish you good luck with the process :)

Javier
+2  A: 

First off (and unrelated): you declare line to be char[100]; however, you are using fgets(line, 1024, file) and fgets(line, 255, file) - these are buffer overruns waiting to happen.

Next, determine what happens when you read a token. For example, I would do:

for(i=0; i<participants; i++)
{
    maleNames[i] = item;
    printf("Token %d: %s", i, item);
    item = strtok(NULL, " ");
}

This will let you know if you have an issue in your input or in your output. Alternatively, step through the loop with a debugger and see exactly what's happening there.

Additionally, I believe that you need to copy the return value of strtok into another character array. Look into strdup to copy your strings.

lacqui
+1  A: 

As @lacqui already mentioned, you had potential buffer overruns. I changed the fgets to pass sizeof(line1)-1 instead of a hard coded value. That way the compiler will figure how what size to pass...even if you later decide to increase / decrease the buffer size. The minus 1 is so fgets will not overwrite the null terminator at the end. I also initialize the buffers using memset.

I also added another line buffer because strtok modifies the string by replacing the specified delimiter chars with null and returning a pointer to a token position in that string...strtok does not make copies.

I changed the delimiters to include \r and \n in addition to spaces.

#include <stdio.h>
#include <string.h>

int main() {
   char line1[100];      //holds line read
   char line2[100];
   char *item;         //item in a line
   char *item2;
   const int participants = 5;   //number of people in the event

   char* maleNames[participants];
   char* femaleNames[participants];

   FILE* file = fopen("names.txt", "r");

   memset(line1, 0, sizeof(line1));
   fgets(line1, sizeof(line1)-1, file);

   int i;
   item = strtok(line1, " \r\n");
   for(i=0; i<participants; i++)
   {
      maleNames[i] = item;  
      item = strtok(NULL, " \r\n");
   }

   //read female names now
   memset(line2, 0, sizeof(line2));
   fgets(line2, sizeof(line2)-1, file);

   item2 = strtok(line2, " \r\n");
   for(i=0; i<participants; i++)
   {
      femaleNames[i] = item2;
      item2 = strtok(NULL, " \r\n");
   }

   for(i=0;i<participants;i++)
   {
      printf("%s %s\n", maleNames[i], femaleNames[i]);
   }

   return 1;
}
dgnorton