Search code examples
cpointerspass-by-referencepass-by-valuefunction-declaration

NEWBIE: passing a pointer to a function


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


Solution

  • 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);