Reputation: 85
I am trying to create a program where it reads in a file with unknown lines and then splits the data by the spaces and then adds it to the struct. I am having trouble with the reading the data in and adding it to the struct. I get a few errors when trying to compile with GCC. Here they are.
program1.c: In function ‘initialize’:
program1.c:54:3: warning: format ‘%d’ expects argument of type ‘int *’, but argument 5 has type ‘int’ [-Wformat=]
if(fscanf(fp, "%s %f %d %s\n", *data[counter].type, data[counter].literAmount, *data[counter].miles, *data[counter].color) !=4) {
^
program1.c:57:2: warning: format ‘%f’ expects argument of type ‘double’, but argument 3 has type ‘float *’ [-Wformat=]
printf("data stored is: %s %f %d %s\n", *data[counter].type, data[counter].literAmount, data[counter].miles, *data[counter].color);
^
program1.c:57:2: warning: format ‘%d’ expects argument of type ‘int’, but argument 4 has type ‘int *’ [-Wformat=]
Here is the code to the program.
#include<stdlib.h>
#include<stdio.h>
typedef struct importedData {
char *type[20];
float *literAmount;
int *miles;
char *color[20];
}DATA;
int main() {
int userInput;
initialize();
//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;
}
int initialize() {
DATA *data = malloc(numberOfLines() * sizeof(*data));
FILE *fp = fopen("hw3.data", "r"); //Opens file name and in the read format
int counter = 0;
int totalIteragions = numberOfLines();
while(counter < totalIteragions) {
if(fscanf(fp, "%s %f %d %s\n", *data[counter].type, data[counter].literAmount, *data[counter].miles, *data[counter].color) !=4) {
return -1;
}
printf("data stored is: %s %f %d %s\n", *data[counter].type, data[counter].literAmount, data[counter].miles, *data[counter].color);
}
}
Could someone explain to me why this error is occurring and how to fix it and in the future catch errors like this? Thanks for all your help.
EDIT: I don't have to make the variables in the struct pointers do I? I am assuming since I make an array of structs using malloc the memory locations will already be allocated so when you enter in data it will store it to each one of those memory locations. Correct?
Upvotes: 1
Views: 3408
Reputation: 5325
Printing and scanning are different.
With scanf
, you are reading an integer into a location in memory, so the argument matching %d
should be a int*
, not int
.
With printf
, you are printing an integer, so the argument matching %d
should be an int
, not an int*
. Same deal with %f
- you should pass either a float
or a double
, not a float *
when trying to print.
There are many other issues with your code and I am inclined to agree with Matt McNab - you appear to be throwing *
around randomly. I suggest looking for a introductory guide on pointers before going any further. Then read about realloc (no need to iterate the file twice...)
Example struct with 100% less *
s:
typedef struct importedData {
char type[20]; // better be careful reading into this
float literAmount;
int miles;
char color[20]; // this too
} DATA;
Scanning/printing:
if(fscanf(fp, "%s %f %d %s\n", data[counter].type, &data[counter].literAmount, &data[counter].miles, data[counter].color) !=4) {
return -1;
}
printf("data stored is: %s %f %d %s\n", data[counter].type, data[counter].literAmount, data[counter].miles, data[counter].color);
However, there is a huge issue with this - you'd be reading potentially more than 20 characters into a 20 character array, which is very bad.
See other questions on this site for how to deal with that.
Upvotes: 1