Thread: How to pass a pointer of a struct to a function

  1. #1
    Registered User drty2's Avatar
    Join Date
    Jan 2009
    Location
    New Zealand
    Posts
    15

    How to pass a pointer of a struct to a function

    This is the code I have... how do I make it so I can access the info in the read_file function in my print_report function?

    Code:
    #include <stdio.h>
    #define MAXRECORDS 4
    
    struct record
    {
       char gender;
       int age;
       int lead;
    };
    
    void read_file();
    void print_report();
    
    int main()
    {
       read_file();
       print_report();
    }
    
    void read_file()
    {
       FILE *fpin;
       int i;
       struct record rec[MAXRECORDS];
    
       fpin = fopen("custsurvey.dat", "r");
    
       if(fpin == NULL)
       {
          printf("Error opening file");
       }
       else
       {
          for(i = 0; i < MAXRECORDS; i++)
             fscanf(fpin, " %c  %d %d", &rec[i].gender, &rec[i].age, &rec[i].lead);
       }
    
       fclose(fpin);
    }
    
    void print_report()
    {
       FILE *fpout;
    
       fpout = fopen("surveyreport.txt", "w");
    
       if(fpout == NULL)
       {
          printf("Error opening file");
       }
       else
       {
          printf("%c  %d %d", rec[0].gender, rec[0].age, rec[0].lead);
       }
    }

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Your first step would have to be to move the rec array into main.
    Since it is an array, you can just pass that as an argument of array/pointer type to the two functions that use the rec array. [Array arguments in C are automatically converted to a pointer to the first element, and pointers can be used in "array form", where the index behaves just like if you had an array of those type of elements].

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Code:
    struct record *read_file();
    void print_report(struct record *ptr);
    
    struct record *read_file()
    {
       FILE *fpin;
       int i;
       struct *record rec[MAXRECORDS]=malloc(sizeof(rec)*MAXRECORDS);
      [....]
       return rec;
    You want to pass a pointer to the beginning of the record. So in main:
    Code:
    int main()
    {
       struct record *ptr=read_file();
       print_report(ptr);
       free(ptr);
    }
    The free() here is kind of superfluous but important to think about.

    ps. matsp's idea may be better for allocating the space. The function prototypes would then be:
    Code:
    void read_file(struct record *ptr);
    void print_report(struct record *ptr);
    Last edited by MK27; 01-18-2009 at 05:48 PM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    MK27 - why do you need to use dynamic memory all of a sudden - it was obviously enough stack for it to work in the original case... It shouldn't change much in the case of the array being placed in main().

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by matsp View Post
    MK27 - why do you need to use dynamic memory all of a sudden - it was obviously enough stack for it to work in the original case... It shouldn't change much in the case of the array being placed in main().

    --
    Mats
    Yes. Let me try and make this up:
    Code:
    int main()
    {
       struct record rec[MAXRECORDS];
       read_file(&rec);
       print_report(&rec);
    }
    Last edited by MK27; 01-18-2009 at 06:03 PM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  6. #6
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by MK27 View Post
    Yes.
    Sorry, I completely misread your post - I thought you put the malloc in main, and then called read_file() with it as an argument.

    Aside from a syntactical error where you are assigning an array of pointers with a single pointer, I'd say I prefer to create a local array variable in main and call read_file() with it as an argument. It saves getting trouble with freeing it later on - imagine that add the filename as an argument, and then rewrite the program to parse through 4000 files's worth of data - then you'd probably run out of memory at some point before it's finished. Alocating memory in a function and then returning that to an upper layer is something that should be done VERY rarely - because the calling code won't know that it's supposed to free that memory, unless it's well documented.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  7. #7
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by MK27 View Post
    Yes. Let me try and make this up:
    Code:
    int main()
    {
       struct record rec[MAXRECORDS];
       read_file(&rec);
       print_report(&rec);
    }
    Address operator is not needed (and may lead to error/warning messages of "incompatible type") if the compiler pays attention.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  8. #8
    Registered User drty2's Avatar
    Join Date
    Jan 2009
    Location
    New Zealand
    Posts
    15
    I read about passing arrays to functions and created this code but I get errors. On the read_file(rec); line I get "error: cannot convert 'record*' to 'rec' for argument '1' to 'void read_file(rec*)'" and on the fscanf line I get three errors of "error: expected primary-expression before '[' token"

    Code:
    #include <stdio.h>
    #define MAXRECORDS 4
    
    struct record
    {
       char gender;
       int age;
       int lead;
    };
    
    void read_file(struct rec[]);
    
    int main()
    {
       struct record rec[MAXRECORDS];
       read_file(rec);
    }
    
    void read_file(struct rec[])
    {
       FILE *fpin;
       int i;
    
       fpin = fopen("custsurvey.dat", "r");
    
       if(fpin == NULL)
       {
          printf("Error opening file");
       }
       else
       {
          for(i = 0; i < MAXRECORDS; i++)
             fscanf(fpin, " %c  %d %d", &rec[i].gender, &rec[i].age, &rec[i].lead);
       }
    
       fclose(fpin);
    
       return;
    }
    Last edited by drty2; 01-18-2009 at 06:23 PM.

  9. #9
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Surely you gave your function parameter a name of some kind?

  10. #10
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by tabstop View Post
    Surely you gave your function parameter a name of some kind?
    Or rather, the name of the struct itself is missing.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  11. #11
    Registered User drty2's Avatar
    Join Date
    Jan 2009
    Location
    New Zealand
    Posts
    15
    oh i forgot the record before rec[] lol, thanks

  12. #12
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Don't forget to put it into the prototype, as well.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  13. #13
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Also note that if fpin is in fact NULL, you'll be calling fclose(NULL), which generally causes a segmentation fault on my machine.

    Finally, you can generally leave whitespace out of *scanf() format strings; scanf() skips over any whitespace it sees under normal circumstances.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Getting an error with OpenGL: collect2: ld returned 1 exit status
    By Lorgon Jortle in forum C++ Programming
    Replies: 6
    Last Post: 05-08-2009, 08:18 PM
  2. Undefined Reference Compiling Error
    By AlakaAlaki in forum C++ Programming
    Replies: 1
    Last Post: 06-27-2008, 11:45 AM
  3. Replies: 16
    Last Post: 10-29-2006, 05:04 AM
  4. Pass struct to a function.
    By Hybird in forum C++ Programming
    Replies: 5
    Last Post: 11-27-2005, 12:12 AM
  5. towers of hanoi problem
    By aik_21 in forum C Programming
    Replies: 1
    Last Post: 10-02-2004, 01:34 PM