I have a school project where I need to read .ppm file in C and store it in a struct to be used for later tasks. Once I get the first line and assign it to a struct variable, I get errors if I try to navigate through the file again. Here is my code:
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int r, g, b;
} pixels;
typedef struct {
int width, height, maxColors;
char *format; //PPM file format
char *comments;
pixels *pixels;
} PPM;
PPM *getPPM(FILE * f) {
// Check if the file is valid. If not then exit the program
if(f == NULL) {
perror("Cannot open file: ");
exit(1);
}
PPM *pic = malloc(sizeof(PPM));
// If memory allocation fails, exit the program.
if(!pic) {
perror("Unable to allocate memory for structure");
exit(1);
}
// Store the first line of file into the structure
char *fileFormat;
if(fgets(fileFormat, sizeof(fileFormat), f) != NULL) {
// If it is a valid .ppm format, then store it in the structure
if(fileFormat[0] == 'P')
pic->format = fileFormat;
} else {
perror("Unable to read line from the input file");
exit(1);
}
//Errors start here
int c = getc(f);
while(c != EOF)
c = getc(f);
/*
char *comments;
if(fgets(comments, sizeof(comments), f) != NULL) {
printf("%s\n", comments);
} else {
perror("Unable to read line from the input file");
exit(1);
}
*/
fclose(f);
return pic;
}
int main(int argc, char **argv) {
PPM *p = getPPM(fopen(argv[1], "r"));
printf(" PPM format = %s",p->format);
return 0;
}
I have tried getting individual characters from the file. I have tried reading the whole line using fgets like I did in the previous step (for fileFormat), but every time it gives out segment fault. I have tried looking at other examples but I cannot figure out the problem. I have been at it for hours, so any help would be greatly appreciated!
Could the problem with the way the memory is allocated? Or do I need to give some sort of pointer to the file when I try to read a new line? I tried finding an answer in man pages but I couldn't figure anything out.
P.S. the while(c != EOF) { c = getc(f); } and the next commented step was just to see if it was working or not. I want to put all the information from the .ppm file into the PPM struct.
You're reading into an uninitialized pointer, so this is going to crash. You need a buffer:
char *fileFormat = malloc(SIZE_OF_FILE_FORMAT);
Additionally sizeof(fileFormat)
returns the size of the pointer which in this case is not what you want. You need the size of the buffer the pointer points to.