Reputation: 85
I am writing a program where I have to read data from a file and then sort them in descending ascending order. I am having trouble with the sorting part of it. How do I sort the float values and then print the struct sorted? Here is my code. I keep getting a segmentation fault. I am not sure how to fix it.
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
typedef struct importedData {
char type[100];
float literAmount;
int miles;
char color[20];
}DATA;
void sorting();
int main() {
int userInput;
//initialize();
DATA *data = NULL;
sorting(data);
//Do while loop to loop through menu until exit.
do {
//Print statements to put out the output options
printf("Choose the option you would like to preform \n");
printf("1.Sort data from the float value & print high to low \n2.Sort data by the float value & print low to high\n3.Sort data by the int value & print high to low\n4.Sort data by the int value & print low to high");
scanf("%d", &userInput); //Scanner to take in the keyboard input
} while (userInput != 5);
return 0;
}
int numberOfLines() {
FILE *fp = fopen("hw3.data", "r"); //Opens file name and in the read format
int c = 0; //Count the number of characters
int count = 0; //Number of lines
if(fp == NULL) { //If file was not able to be opened program will exit
printf("Unable to read file. Closing");
return 0;
}
while((c = fgetc(fp)) != EOF) { //Get the character and make sure it isnt the END OF FILE
if(c == '\n') { //If the charcter is set to \n (New Line) will add one to counter
count++;
}
}
fclose(fp);
return count;
}
DATA* initialize(DATA *data) {
data = malloc(numberOfLines() * sizeof(*data));
FILE *fp = fopen("hw3.data", "r"); //Opens file name and in the read format
int counter = 0;
int totalIterations = numberOfLines();
while(counter < totalIterations) {
if(fscanf(fp, "%s %f %d %s\n", data[counter].type, &data[counter].literAmount, &data[counter].miles, data[counter].color) !=4) {
}
printf("data stored is: %s %f %d %s\n", data[counter].type, data[counter].literAmount, data[counter].miles, data[counter].color);
}
return (data);
}
void sorting() {
DATA *data = malloc(numberOfLines() * sizeof(*data));
FILE *fp = fopen("hw3.data", "r"); //Opens file name and in the read format
int counter = 0;
int totalIterations = numberOfLines();
while(counter < totalIterations) {
if(fscanf(fp, "%s %f %d %s\n", data[counter].type, &data[counter].literAmount, &data[counter].miles, data[counter].color) ==4) {
counter++;
}
}
DATA *temp;
int i, j;
for(i = 0; i < (numberOfLines() -1); i++) {
for(j = 0; j < (numberOfLines() -1); j++) {
if(data[i].literAmount > data[i+1].literAmount) {
data[i].literAmount = (*temp).literAmount;
printf("Temp: %f", (*temp).literAmount);
}
}
}
}
Upvotes: 0
Views: 84
Reputation: 53036
You can have these 4 comparison functions
int compare_literAmount(const void *const lhs, const void *const rhs)
{
if ((lhs == NULL) || (rhs == NULL))
return -1;
return ((int)(((DATA *)lhs)->literAmount)) - ((int)(((DATA *)rhs)->literAmount));
}
int compare_type(const void *const lhs, const void *const rhs)
{
if ((lhs == NULL) || (rhs == NULL))
return -1;
return strcmp(((DATA *)lhs)->type, ((DATA *)rhs)->type);
}
int compare_miles(const void *const lhs, const void *const rhs)
{
if ((lhs == NULL) || (rhs == NULL))
return -1;
return (((DATA *)lhs)->miles) - (((DATA *)rhs)->miles);
}
int compare_color(const void *const lhs, const void *const rhs)
{
if ((lhs == NULL) || (rhs == NULL))
return -1;
return strcmp(((DATA *)lhs)->color, ((DATA *)rhs)->color);
}
and then after reading the data you can
qsort(data, numberOfItems, sizeof(*data), compare_literAmount);
to sort by the literAmmount
field, and so on.
Your initialize()
function is also very weak, make it more robust by adding some checks, and you could cause an inifinite loop in while (counter < totalIterations)
, because you didn't check that all lines were valid in numberOfLines()
, also it would be better if you pass fp
to numberOfLines()
instead of openning and closing the file there.
This is a suggestion of fixes to your initialize()
function
DATA* initialize(DATA *data) {
int totalCount = numberOfLines();
int count = 0;
data = malloc(totalCount * sizeof(*data));
if (data == NULL)
return NULL;
FILE *fp = fopen("hw3.data", "r"); //Opens file name and in the read format
if (fp == NULL)
{
free(data);
return NULL;
}
/* write a safer format string */
while(fscanf(fp, "%99s%f%d%19s\n", data[count].type, &data[count].literAmount, &data[count].miles, data[count].color) == 4)
count++;
qsort(data, count, sizeof(*data), compare_literAmount);
for (int i = 0 ; i < count ; i++)
printf("data stored is: %s %f %d %s\n", data[count].type, data[count].literAmount, data[count].miles, data[count].color);
return (data);
}
notice that the first thing I did was to store the value of the number of lines in the file. Because it would be more efficient.
Upvotes: 1