ykh
ykh

Reputation: 1835

Reading input file into struct and sort data?

I have the following input file:

WO98EKOYMPCAUEWT0 Honda Civic 2011 4
7W32UAERZFBCB3S6P Chevrolet Tahoe 2011 6
DNU7XQO8LLA9I6YFX Toyota Tercel 2012 4
DNU7XQO8LLA9I6YFX Toyota Tercel 2012 4
DNU7XQO8LLA9I6YFX Toyota Tercel 2012 4
7W32UAERZFBCB3S6P Chevrolet Tahoe 2011 6

This is actually a task that we were handed, and i have been struggling for a few days with no results.

Here is my code so far:

struct Car
{
       char *CarMake;
       char *CarModel;
       char *CarMakeYear;
       int Occurances;
};

int main(int argc, char *argv[])
{
  //File related
  FILE *inputFile, *outputFile; 
  char fileName[] = "";

  //Struct related
  int carCounter = 0;
  struct Car cars[50];

  struct Car car;
  car.CarMake  = (char*)malloc( 200 *sizeof(char));
  car.CarMakeYear  = (char*)malloc( 200 *sizeof(char));
  car.CarModel  = (char*)malloc( 200 *sizeof(char));
  car.Occurances = 0;  

  printf("Please enter file name:",  fileName);
  scanf("%s",fileName);
  inputFile = fopen(fileName,"r"); 

  while(fscanf(inputFile, "%*s %s %s %s %*s\n",car.CarMake, car.CarModel,car.CarMakeYear ) != EOF)
  {         
   cars[carCounter].CarMake = car.CarMake;                     
    carCounter++;
  }
  fclose(inputFile);

  int i=0;
  for(i=0;i<6;i++)
   printf("%s %s %s \n", cars[i].CarMake, cars[i].CarModel,cars[i].CarMakeYear);

  system("PAUSE");  
  return 0;
}

The printf above will take the last array value and keeps printing which means it's not working. Anybody please help with this, i have till before midnight till submit.

Upvotes: 0

Views: 3878

Answers (2)

Drew McGowen
Drew McGowen

Reputation: 11706

cars[carCounter].CarMake = car.CarMake;

This line is the issue. In C, you can't simply make a copy of a string with the assignment operator. You must allocate a new buffer for the string and copy it:

cars[carCounter].CarMake = malloc(strlen(car.CarMake) + 1); // plus one to include the null-terminator
strcpy(cars[carCounter].CarMake, car.carMake);

Depending on what platform/compiler you're using, you can use the strdup function, which essentially does the exact same:

cars[carCounter].CarMake = strdup(car.CarMake);

Don't forget to free the memory when you're done.

EDIT:

There's another issue with grabbing the file name from user input. The line char fileName[] = ""; doesn't leave any room for actual text - try something like char fileName[100];. Even if it works now, it's not guaranteed to continue working; it's never safe to rely on undefined behavior.

Upvotes: 5

Gar
Gar

Reputation: 862

I'd write it this way :

struct Car
{
       char *CarMake;
       char *CarModel;
       char *CarMakeYear;
       int Occurances;
};

int main(int argc, char *argv[])
{
  //File related
  FILE *inputFile, *outputFile; 
  char fileName[] = "";

  //Struct related
  int carCounter = 0;
  struct Car cars[50];

  struct Car car;
  car.CarMake  = (char*)malloc( 200 *sizeof(char));
  car.CarMakeYear  = (char*)malloc( 200 *sizeof(char));
  car.CarModel  = (char*)malloc( 200 *sizeof(char));
  car.Occurances = 0;  

  printf("Please enter file name:",  fileName);
  scanf("%s",fileName);
  inputFile = fopen(fileName,"r"); 

  while(fscanf(inputFile, "%*s %s %s %s %*s\n",car.CarMake, car.CarModel,car.CarMakeYear ) != EOF)
  {         

   cars[carCounter].CarMake = car.CarMake;                     
  //-- change starts here
  // the values of the car struct being pointed to by the current carCounter array placeholder
  // you allocate a new car so that you won't be touching the old ones.
  car.CarMake  = (char*)malloc( 200 *sizeof(char));
  car.CarMakeYear  = (char*)malloc( 200 *sizeof(char));
  car.CarModel  = (char*)malloc( 200 *sizeof(char));
  //-- change ends here
    carCounter++;
  }
  fclose(inputFile);

  int i=0;
  for(i=0;i<6;i++)
   printf("%s %s %s \n", cars[i].CarMake, cars[2].CarMake,cars[3].CarMake);

  system("PAUSE");  
  return 0;
}

Upvotes: 0

Related Questions