Thread: Passing pointers to functions in seperate source files

  1. #1
    Registered User
    Join Date
    Oct 2009
    Location
    Edmonton, Canada
    Posts
    5

    Passing pointers to functions in seperate source files

    Hi Everybody,

    I'm brand new here and this is my first post...

    I think my question is straight forward - I'm fairly new to C but I have to this point written many small useless programs that use structs, pointers and functions.

    I have no problem passing the address of a struct array to a function and I have no issues getting the functions to perform their specific tasks to the struct arrays - as long as all my code is in the same source file.

    This is my problem. Early in my introduction to C I got in the habit of keeping the source file containing main() small, and having separate source files containing like functions.

    I was having little to no difficulty maintaining this until I started to pass pointers around. Now I can't seem to compile without error unless all my code is in the same source file.

    Any ideas on what I might be doing wrong? Is this in fact bad practice to be using separate source files?

    Here's an example.. this program compiles and runs as I intended it to. But if I put the functions newDriver() and displayDriver in a seperate source file I cannot get the program running to save my life.


    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    struct person
    {
    	char lastName[20];
    	char firstName[20];
    	char age[4];
    	char position[20];
    };
    
    typedef struct person person;
    
    int counter = 0;
    int displayCounter;
    
    person *empPtr;
    
    newDriver(person *empPtr)
    {
    	fputs("\n*New Driver Entry\n", stdout);
    	fputs("Enter driver last Name: ", stdout);
    	fgets(empPtr[counter].lastName, 20, stdin);
    	fflush(stdin);
    	empPtr[counter].lastName[strlen(empPtr[counter].lastName) - 1] = '\0';
    
    	fputs("Enter driver first Name: ", stdout);
    	fgets(empPtr[counter].firstName, 20, stdin);
    	fflush(stdin);
    	empPtr[counter].firstName[strlen(empPtr[counter].firstName) - 1] = '\0';
    
    	fputs("Enter driver age: ", stdout);
    	fgets(empPtr[counter].age, 4, stdin);
    	fflush(stdin);
    	empPtr[counter].age[strlen(empPtr[counter].age) - 1] = '\0';
    
    	fputs("Enter driver position: ", stdout);
    	fgets(empPtr[counter].position, 20, stdin);
    	fflush(stdin);
    	empPtr[counter].position[strlen(empPtr[counter].position) - 1] = '\0';
    }
    
    displayDriver(person *empPtr)
    {
    	fputs("\n*Display Driver Entries\n", stdout);
    	
    	for(displayCounter =0; displayCounter < counter; displayCounter++)
    	{
    		printf("%s, %s\t\t\t%s\t%s\n", empPtr[displayCounter].lastName,
    						empPtr[displayCounter].firstName, empPtr[displayCounter].age,
    							empPtr[displayCounter].position);
    	}	
    }
    
    int main(void)
    {
    	
    	char userSay[10];
    
    	
    	empPtr = malloc(20 * sizeof(person));
    	
    	if(empPtr == NULL)
    	{		
    		printf("There was a memory allocation problem.\n");
    		exit(1);
    	}
    	
    	fputs("*** Taxi Employee Database ***\n\n", stdout);
    
    	do
    	{
    		fputs("--->", stdout);
    		fgets(userSay, 10, stdin);
    		fflush(stdin);
    		userSay[strlen(userSay) - 1] = '\0';
    		
    		if(!strcmp(userSay, "quit"))
    		{
    			fputs("\nGoodbye!\n", stdout);
    		}
    		else if(!strcmp(userSay, "new"))
    		{
    			newDriver(empPtr);
    			counter++;
    		}
    		else if(!strcmp(userSay, "display"))
    		{
    			displayDriver(empPtr);
    		}
    		else
    		{
    			fputs("Unknown Entry\n", stdout);
    		}		
    
    	}while(strcmp(userSay, "quit"));
    
    	free(empPtr);
    
    	exit(0);
    }

  2. #2
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    You should post the code that doesn't work instead of the code that works. How exactly are the functions split up? Which header files are the prototypes defined in? Are you including those header files? Is your compiler correctly linking the compiled object files?

    We need to see the code, and the error messages.
    bit∙hub [bit-huhb] n. A source and destination for information.

  3. #3
    Registered User
    Join Date
    Oct 2009
    Location
    Edmonton, Canada
    Posts
    5
    My question was general - not specific to this example... Generally I would simply have the functions in another source file and would have the same header files seen here as well as declarations to all the external variables. This works in other programs I've coded but not with pointers. So I figure I am missing something I just can't find what.

    Prototypes - although I understand they are a good idea to catch compilation issues are not actually "required" for anything correct?

  4. #4
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    There is nothing at all that would prevent you from doing what you described. That's why we need to see an example which doesn't work, so we can point out what you did wrong.

    Prototypes - although I understand they are a good idea to catch compilation issues are not actually "required" for anything correct?
    Prototypes are just the functions declared in the header file. They are needed if you are going to call a function from a different source file.
    bit∙hub [bit-huhb] n. A source and destination for information.

  5. #5
    ... kermit's Avatar
    Join Date
    Jan 2003
    Posts
    1,534
    bithub is right - show us an example of what does *not* work for you. Splitting code up into various files is quite common, and should give no issues, provided you are doing things right.

    As for prototypes, if you are using a modern compiler, they are definitely necessary.

  6. #6
    Registered User
    Join Date
    Oct 2009
    Location
    Edmonton, Canada
    Posts
    5
    ok thanks - I was unaware prototypes were required. And unsure exactly how to declare them in this example using type person....

    I've tried 50 different ways but here's an example of 1...

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    extern int counter;
    extern int displayCounter;
    extern struct person
    extern struct person *empPtr;
    
    
    newDriver(person *empPtr)
    {
    	fputs("\n*New Driver Entry\n", stdout);
    	fputs("Enter driver last Name: ", stdout);
    	fgets(empPtr[counter].lastName, 20, stdin);
    	fflush(stdin);
    	empPtr[counter].lastName[strlen(empPtr[counter].lastName) - 1] = '\0';
    
    	fputs("Enter driver first Name: ", stdout);
    	fgets(empPtr[counter].firstName, 20, stdin);
    	fflush(stdin);
    	empPtr[counter].firstName[strlen(empPtr[counter].firstName) - 1] = '\0';
    
    	fputs("Enter driver age: ", stdout);
    	fgets(empPtr[counter].age, 4, stdin);
    	fflush(stdin);
    	empPtr[counter].age[strlen(empPtr[counter].age) - 1] = '\0';
    
    	fputs("Enter driver position: ", stdout);
    	fgets(empPtr[counter].position, 20, stdin);
    	fflush(stdin);
    	empPtr[counter].position[strlen(empPtr[counter].position) - 1] = '\0';
    }
    
    
    
    displayDriver(person *empPtr)
    {
    	fputs("\n*Display Driver Entries\n", stdout);
    	
    	for(displayCounter =0; displayCounter < counter; displayCounter++)
    	{
    		printf("%s, %s\t\t\t%s\t%s\n", empPtr[displayCounter].lastName,
    						empPtr[displayCounter].firstName, empPtr[displayCounter].age,
    							empPtr[displayCounter].position);
    	}	
    
    }

  7. #7
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    So it never hurts to do a valid prototype, namely one that includes a return type. Are you intending to hide your global empPtr variable with the one passed in? You still need "struct" in a prototype.

  8. #8
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    You need to include whatever header file "person" was defined in.
    bit∙hub [bit-huhb] n. A source and destination for information.

  9. #9
    Registered User
    Join Date
    Oct 2009
    Location
    Edmonton, Canada
    Posts
    5
    ok - that sounds maybe like what I'm looking for...

    Your saying I should put something like the following into a header file and include the header file in all the source files, instead of declaring them globaly?

    Code:
    typedef struct person
    {
    	char lastName[20];
    	char firstName[20];
    	char age[4];
    	char position[20];
    } person;

  10. #10
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    Yes, it should be included in all source files that need to use that structure.
    bit∙hub [bit-huhb] n. A source and destination for information.

  11. #11
    Registered User
    Join Date
    Oct 2009
    Location
    While(1)
    Posts
    377
    See i think u should have header files also where there will only be signature of the functions and where and in a separate .cc file u should define them.
    And where ever u want to use them just include the header files.
    And please put header guards

  12. #12
    Registered User
    Join Date
    Oct 2009
    Location
    Edmonton, Canada
    Posts
    5
    Quote Originally Posted by bithub View Post
    Yes, it should be included in all source files that need to use that structure.
    Thanks bithub. This led me down the path that got everything working! This has been driving me crazy for days. If anyone reading this has the same problem I just declared the structure, the typedef and the structure pointer in a header file. Then included the header file in both source files.

    For the record though.. I didn't use prototypes at all. Everything compiled without even warnings.

  13. #13
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Do not dismiss the prototypes. Calling functions without prototypes can cause hard-to-spot bugs and errors.
    Use them, even if they are not required. Always.
    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.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Trouble passing args to functions in other files
    By Midnight Coder in forum C Programming
    Replies: 6
    Last Post: 01-03-2009, 05:13 PM
  2. Replies: 7
    Last Post: 04-19-2006, 11:17 AM
  3. passing pointers at structs thru functions
    By nunnu in forum C Programming
    Replies: 2
    Last Post: 05-12-2004, 09:16 AM
  4. Passing data/pointers between functions #2
    By TankCDR in forum C Programming
    Replies: 1
    Last Post: 11-02-2001, 09:49 PM
  5. Passing data/pointers between functions
    By TankCDR in forum C Programming
    Replies: 1
    Last Post: 11-02-2001, 12:59 AM

Tags for this Thread