Reputation: 1835
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.
Upvotes: 0
Views: 3878
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
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