Home > database >  NEWBIE: passing a pointer to a function
NEWBIE: passing a pointer to a function

Time:04-06

I'm trying to relearn C from dabbling with it about 5 year ago. Specifically, I'm trying to learn how to extract a number of operations from main and make them into a function, with the aim of moving them to a library file next.

This seems to be working:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

struct arguments {
  char *word_file;  /* Default name for input file */
} arguments;

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

  arguments.word_file = "dummy";
  
  FILE *fp;
  fp = fopen(arguments.word_file, "r");
  if (fp == NULL) { /* If fopen failed... */
    fprintf(stderr, "Error: Unable to open file %s: %s\n",
        arguments.word_file, strerror (errno));
    exit (8);
  }

  char word[60];
  fgets (word, sizeof(word), fp);
  printf("Word is %s\n", word);
}

By the way, 'dummy' is:

$ cat dummy
dog
cat
$ 

No matter how I try this, it either gives me compile errors, or seg faults when I run it:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

struct arguments {
  char *word_file;  /* Default name for input file */
} arguments;

void getfile(FILE *fp) {  
  fp = fopen(arguments.word_file, "r");
  if (fp == NULL) { /* If fopen failed... */
    fprintf(stderr, "Error: Unable to open file %s: %s\n",
        arguments.word_file, strerror (errno));
    exit (8);
  }
}

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

  arguments.word_file = "dummy";
  
  FILE *fp;
  getfile(fp);
  
  char word[60];
  fgets (word, sizeof(word), fp);
  printf("Word is %s\n", word);
}

I've tried changing from *fp to fp to &fp without success. I'm sure that there's something that I don't understand about file pointers, but can't figure it out.

Thanks for any help and suggestions.

-Kevin

CodePudding user response:

You have two choices

First, have 'getfile' return the file handle (this is the most idiomatic way in c)

FILE *getfile() {  
  FILE *fp = fopen(arguments.word_file, "r");
  if (fp == NULL) { /* If fopen failed... */
    fprintf(stderr, "Error: Unable to open file %s: %s\n",
        arguments.word_file, strerror (errno));
    exit (8);
  }
  return fp;
}

and in main

FILE *fp =  getfile(fp);

or have getfile update the fp value based , using c-style 'pass by reference'

void getfile(FILE **fp) {  
  *fp = fopen(arguments.word_file, "r");
  if (*fp == NULL) { /* If fopen failed... */
    fprintf(stderr, "Error: Unable to open file %s: %s\n",
        arguments.word_file, strerror (errno));
    exit (8);
  }
}

in main

File *fp = NULL;
getfile(&fp);

CodePudding user response:

fp shouldn't be an argument to getfile(), it should be the return value.

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

struct arguments {
  char *word_file;  /* Default name for input file */
} arguments;

FILE *getfile() {  
  FILE *fp = fopen(arguments.word_file, "r");
  if (fp == NULL) { /* If fopen failed... */
    fprintf(stderr, "Error: Unable to open file %s: %s\n",
        arguments.word_file, strerror (errno));
    exit (8);
  }
  return fp;
}

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

  arguments.word_file = "dummy";
  
  FILE *file_ptr;
  file_ptr = getfile();
  
  char word[60];
  fgets (word, sizeof(word), file_ptr);
  printf("Word is %s\n", word);
}

If there's some reason you really need to pass it as a parameter, see Changing address contained by pointer using function

CodePudding user response:

The problem is that the pointer fp is passed to the function getfile by value.

getfile(fp);

That is the function deals with a copy of the value of the passed pointer fp. So changing the copy in the function does not reflect on the value of the original pointer.

You need to pass the pointer by reference.

In C passing by reference means passing an object indirectly through a pointer to it. Dereferencing the pointer you can get a direct access to the original object.

So declare and define the function like

void getfile(FILE **fp) {  
  *fp = fopen(arguments.word_file, "r");
  if ( *fp == NULL) { /* If fopen failed... */
    fprintf(stderr, "Error: Unable to open file %s: %s\n",
        arguments.word_file, strerror (errno));
    exit (8);
  }
}

and call the function like

getfile(&fp);
  • Related