0

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.

  • Read each line and put the values of the second, third and fourth in a struct.

  • After that add a new column which are the number of occurrences based on the 3 columns above.

  • Sort data by second, thrid and fourth. and then output them in a file.

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.

2 Answers 2

5
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.

Sign up to request clarification or add additional context in comments.

2 Comments

Can you help me on the occurances and sorting.
@drew I want to have a little chat with you. Are you avaiable?
0

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;
}

4 Comments

It'd be wise to say what changed, and why you changed it. Also, by allocating memory in car.CarMake and such, it's not obvious what's happening.
euh .. i thought it was obvious, he wasn't allocating the memory for the new records, he did that only once, reallocating will solve his problem, i'll add an inline comment about it.
What he re-allocated memory for the variables, and it actually worked.
Yes, it works, but it would make more sense to store the allocated block in cars[carCounter].CarMake and strcpy to it - makes it more readable.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.