user6913230
user6913230

Reputation:

Reading a file and storing it in a struct so that it can be used throughout other functions

So I am trying to write a program that will read a file and store into a struct, such that it can be later on passed to other functions for manipulation and whatnot. However, when I try and access this file for later functions it seems nothing has been stored/buffered. The problem seems to be in the "void readFile" function. Here's what I have so far:

Sample input: Mary had a little lamb,
Mary had a little lamb, whose fleece was white as snow.

My debug would print this out correctly however with the last line repeated.

struct info{
    int numOfLines;
    char lines[];
}

int main (int argc, char * argv[]){

     int words, sentences, syllables;
     int index = 0;
     struct info lines[200];
     FILE* inFile = NULL;
     inFile = findFile(argv[1]);
     readFile(inFile,lines);
     fclose(inFile);
    return 0;
}
FILE* findFile(char fileName[]){

    FILE* fileIn = NULL;
    fileIn = fopen(fileName, "r");

    while(fileIn == NULL){
    printf("That file does not exist or was unable to be found, please enter another\n");
    fgets(fileName,100,stdin);  
    fopen(fileName, "r");
    }

    return fileIn;
}

void readFile(FILE* toRead, struct info lines[]){
     char sentence[200];
     int i = 0;

    while(!feof(toRead)){
         fgets(sentence,300,toRead); //Would this be better than fread()?
         strcpy(lines[i].lines,sentence);
         printf("%s",lines[i].lines);     //*This is a debug statement. The lines are read properly except the last line is printed twice. not sure why. 
         i++;
    }
}

Edit: looking back at it now, would it have been a better idea to use pointers for this instead of a string array?

Upvotes: 0

Views: 146

Answers (2)

Simon Lit
Simon Lit

Reputation: 11

So i will try to answer your question even though it is a bit vague. So regarding your question I don't know if you are trying to read out a file that is full of "Info structs" or trying to read 'x' amount of char into a struct from a text/bin file.

First some general things I see in your code.

  • This function FILE* findFile(char fileName[]) is a bit unnecessary. As far I can see you are trying to see if the file exist. You can do this by using the "acces()" this function checks whether the calling process an access the file path name. Implementation would be like this If(access(pathOfFile, F_OK) == 0){}. Read this link for more information https://linux.die.net/man/2/access.
  • Following code snippets char sentence[200]; fgets(sentence,300,toRead); //Would this be better than fread()?, you declare an char array from a size of 200 then you try to read from the file into it but the amount you try to read is 300 so this will never work because you would be writing outside of your array. Tip read "man" pages you can do this by typing into your linux terminal "man fread", replace fread by other function names. Like "access".

These where two points I wanted to clear up. Regarding your question I will give you an example of reading structs from a file. Because your question So I am trying to write a program that will read a file and store into a struct, such that it can be later on passed to other functions for manipulation and whatnot. is a bit vague if you are trying to read just some chars from a file or structures. So I rewrote your program to read structs from a file full of INFO structs into an array that you then can use to manipulate.

Code snippet read data from a file of structures into an array of structs

#include <stdio.h>
#include <unistd.h>

#define file_name "Foo_File"

struct INFO{
  char ar[200];
}

int main (int argc, char * argv[]){
  if(access(file_name, F_OK) != 0{
    printf("File does not exist");
    return -1;//Exit program with -1, error
  }
  int structs = get_Amount_Of_Structs(file_name);
  INFO info_array[structs];//Make an array of info structs, same amount of structs as in file
  for(int i = 0; i < structs; i++){
    readDataStructFromFile(file_name, info_array, i);
  }
  return 0;
}

/*
  This function will calculate the total byte size of the     file by diving this through the byte size of one struct     you are able to know the amount of structs. 
*/
int get_Amount_Of_Structs(char* filename)
{
	FILE* fp = fopen(filename, "r");
	if(fp == NULL){//If File pointer is null opening failed
		return -1;
  }
	fseek(fp, 0L, SEEK_END);
	int amountOfStructs = ftell(fp)/sizeof(INFO);
	fseek(fp, 0L, SEEK_SET);
	fclose(fp);
	return amountOfStructs;
}

/*
  This function reads a struct from a file at the position     "pos" by slight modification you can make it read the       whole file into a pointer that points to an array of INFO   structs
*/
int readDataStructFromFile(char* filename, INFO* data, int pos)
{
	FILE* fp = fopen(filename, "r");
	if(fp == NULL)
	{
		fclose(fp);
		return -1;
	}
	fseek(fp, (pos * sizeof(INFO)), SEEK_SET);
	int rv = fread(data, sizeof(INFO), 1, fp);
	fclose(fp);
	if(rv == 1)
	{
		return 0;
	}
	return -1;
}

I hope this at least helps you solving your problems with your code. Regarding the "fgets vs fread" question is already solved by another. Wish I could give a more complete answer to your question but there it's a bit to vague.

p.s. If anybody from the community sees faults in my code/explanation, feel free to edit or point out my mistakes. I'm a student so there is always some left to learn.

Upvotes: 1

David Ranieri
David Ranieri

Reputation: 41017

fgets(fileName,100,stdin);
fopen(fileName, "r");

fgets includes the trailing new-line, remove it before using fopen:

char *ptr;
fgets(fileName,100,stdin);
if (ptr = strchr(filename, '\n') {
    *ptr = '\0';
}

also note that you need

fileIn = fopen(fileName, "r");

instead of

fopen(fileName, "r");

Upvotes: 0

Related Questions