2

I am trying to read through the file given then tokenize it. The only problem im having is fgets.The file open recieves no errors. I have seen this elsewhere on the site however no matter how i set this up including setting fileLine to a set amount like (char fileline [200]) i get a segmentation fault. Thanks in advance for any help.

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <unistd.h> int main(int argc, char *argv[]){ char *fileName = "0"; char *tokenize, *savePtr; struct Record *database= malloc(sizeof(database[0])); int recordNum =0; char *fileLine = malloc(sizeof(char *));//have replaced with fileline[200] still didnt work FILE *fd = open(fileName,O_RDWR); if(fd< 0){ perror("ERROR OPENING FILE"); } while(fgets(fileLine,200,fd) !=NULL){ printf("%s\n", fileLine); tokenize = strtok_r(fileLine,",",&savePtr); while(tokenize != NULL){ //TOKENIZING into a struct } } 
5
  • 2
    you're telling fgets to fetch 200 chars into a string that's been malloced to be sizeof(*char), e.g. 200 bytes into a 4 BYTE variable (e.g. size of a pointer to a string). you need malloc(200 * sizeof(char)) Commented Apr 16, 2015 at 18:25
  • sizeof(char) == 1 always Commented Apr 16, 2015 at 18:27
  • @MarcB even when ive used what you suggested or when ive made it a set array of 200(char fileLine[200];) i still get a segmentation fault. Commented Apr 16, 2015 at 18:30
  • @iharob the second while loop is not the issue. i have run this without fgets and it tokenizes properly with a hardcoded fileLine. The issue is at the fgets because i never make it to the printf statement afterword. Commented Apr 16, 2015 at 18:35
  • @justin that's just wrong, you can't be sure. Undefined behavior does not always happen the same way, it's undefined. Commented Apr 16, 2015 at 18:36

3 Answers 3

8

Why use open() with FILE? Use fopen() instead.

#include <stdio.h> #include <string.h> int main(int argc, char *argv[]) { char *fileName = "test.txt"; char *tokenize, *savePtr; char fileLine[200] = {0}; // init this to be NULL terminated FILE *fd = fopen(fileName, "r"); if (fd == 0) { // error check, equal to 0 as iharob said, not less than 0 perror("ERROR OPENING FILE"); return -1; } while (fgets(fileLine, 200, fd) != NULL) { printf("%s\n", fileLine); tokenize = strtok_r(fileLine, ",", &savePtr); while (tokenize != NULL) { tokenize = strtok_r(NULL, ",", &savePtr); // do not forget to pass NULL //TOKENIZING into a struct } } fclose(fd); return 0; } 

As Weather Vane said, fd < 0 would work if you used open(). However, with fopen(), you should check to see if the pointer is NULL, ecquivalently fd == 0.


A comparison between this functions that open a file can be found in:

  1. open and fopen function
  2. C fopen vs open

The way I have it in mind is that fopen() is of higher level.

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

14 Comments

Wow, I didn't see that ... note that fd < 0 would be wrong.
Note: OP is using open, not fopen. So fd < 0 would have been OK, but he wrote *fd = open()
Agreed @AlterMann, edited, thanks! I could also get rid of stdlib too I guess.
Me neither @chux, thanks for the nice discussion. :)
Don't forget to call fclose(fd); afterwards.
|
2

This line

char *fileLine = malloc(sizeof(char *)); 

allocates memory for a char * type, 4 or 8 bytes (depending on the platform).

So when you do

fgets(fileLine,200,fd) 

it expects there to be 200 bytes of memory available.

Try this:

char *fileLine = malloc(200); if (fileLine == NULL) { ... } // check for error 

which will allocate the memory required.

Comments

1

You are using open() instead of fopen().

You can't be sure that the file did open correctly because fopen() does not return an integer, but a pointer to a FILE * object, on failure it returns NULL, so the right codition is

FILE *file; file = fopen(filename, "r"); if (file == NULL) { perror("fopen()"); return -1; } 

In your code, you still go and use fgets() even when the fopen() fails, you should abort the program in that case.

Also, malloc() takes the number of bytes as the size parameter, so if you want fgets() to be limited to read just count bytes, then malloc() should be

char *buffer; size_t count; count = 200; /* or a value obtained someway */ buffer = malloc(count); if (buffer == NULL) { fclose(file); perror("malloc()"); return -1; } 

All the problems in your code would be pointed out by the compiler if you enable compilation warnings.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.