Thread: How do you return a value and pointer from a function?

  1. #1
    Registered User
    Join Date
    Nov 2011
    Posts
    11

    How do you return a value and pointer from a function?

    I know how to use return to pass back a value and/or a pointer but would like to do both.

    Code:
    //EX:  Not sure I declared ptrStrgPlus4 correctly to have it be
    // a pointer to strg+4 (ie '.') on return from the getBoth function
    int num;  char strg[5]="123.456"; char *ptrStrgPlus4; 
    
       x = getBoth(10, strg, *ptrStrgPlus4);
    
    // Would like to return the num*10, plus a pointer to the '.'
    int function getBoth(num, string, *stringPtr) {
        // I know the next line doesn't work
          *stringPtr = string+4;     // Return pointer to 4th char in the string
          return (num*10);
    }
    Any examples or help would be greatly appreciated.

  2. #2
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    How about stuffing the two types viz., int and char* into a struct and returning that.

  3. #3
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by bobv View Post
    I know how to use return to pass back a value and/or a pointer but would like to do both.

    Code:
    //EX:  Not sure I declared ptrStrgPlus4 correctly to have it be
    // a pointer to strg+4 (ie '.') on return from the getBoth function
    int num;  char strg[5]="123.456"; char *ptrStrgPlus4; 
    
       x = getBoth(10, strg, *ptrStrgPlus4);
    
    // Would like to return the num*10, plus a pointer to the '.'
    int function getBoth(num, string, *stringPtr) {
        // I know the next line doesn't work
          *stringPtr = string+4;     // Return pointer to 4th char in the string
          return (num*10);
    }
    Any examples or help would be greatly appreciated.
    It's pretty simple... you can't. C functions can return only a single value.

    itCbitC has one possible solution.

    However, common sense would provide a better one... A proper function performs one task in a self-contained manner. I know it may be "for example only" but in real world programming the smart thing would be to split your function into two separate functions, each doing their own thing.

  4. #4
    Registered User
    Join Date
    Nov 2011
    Posts
    11
    If that's the only way then I wil try that. BTW, what viz?

    I used to do a lot of C coding back in the Kernighan & Ritchie days and swear I did this ... just can't seem to remember how and it's frustrating me.

  5. #5
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    Viz - Wikipedia, the free encyclopedia.

    Option other instead of returning are pass by reference.

    Tim S.

  6. #6
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Once again the real question is: Why would you want to? You have one function doing two totally disparate things... that amounts to "Write 2 functions".

    However, if you are bent upon doing this as one function call, you can use the modified value of stringptr after the function returns.

  7. #7
    Registered User
    Join Date
    Nov 2011
    Posts
    11
    Thanks you all for your help.

    The example I gave is not what I'm trying to do, just a simplified example of the problem. I

    'm trying to break up the user inputed IP address (ex: 192.16.1.10) into it's quadrants and want to return each quadrant (ex 192) and point to the next char '.' so I don't have to keep parsing for the beginning of teh next quadrant. I'm using a minimized Linux OS (MicroBlaze) that fits into an FPGA that doesn't support scanf and many other functions. User input is via a serial port and is just single byte that I concatanate into a string. Since the user can create bad addresses and other funky inputs I'm trying to test for these things while I'm parsing the string. I can use the struct solution which is pretty good but am trying to also recall the intracies and many possibilities of C.

    I believe the pass by reference is what I'm looking for. Cany anyone suggest how I'd modify the code to achieve this?

  8. #8
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    A "dotted quad" address can be packed into a 32bit unsigned int very easily. the allowed range in each segment is 0 to 255 (an unsigned char). This you can easily pack into an unsigned int with each of the 4 values occupying one byte (in fact, that's how it's stored in socket structs). ... all done in one call.
    Last edited by CommonTater; 11-22-2011 at 11:47 AM.

  9. #9
    Registered User
    Join Date
    Nov 2011
    Posts
    11
    Any example? When you know how everything seems easy, but if you don't well... I know it's a u32 and what the values are but getting it there is another story, at leaset for me. The fact that the 4 bytes need to be in little endian format is another matter but I can deal w/that.

  10. #10
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    Quote Originally Posted by bobv View Post
    I believe the pass by reference is what I'm looking for. Cany anyone suggest how I'd modify the code to achieve this?
    Pass by reference is also called pass by pointer or address.

    Your code make no sense to me; so I can not fix it; even if I had the time to do it.

    Tim S.

  11. #11
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Technically, C does not have pass by reference. Everything is pass by value. To allow a function to change the value of a parameter passed in, and have that change remain after the function exits, you have to pass a pointer to the thing. For example:
    Code:
    #include <stdio.h>
    
    
    void foo(int x)
    {
        x = 17;
        printf("In foo(), x = %d\n", x);
    }
    
    
    void bar(int *x)
    {
        *x = 17;  // x is a pointer, *x is the number stored at that address
        printf("In bar(), x = %d\n", *x);
    }
    
    
    int main(void)
    {
        int x = 42;
    
    
        printf("In main, x = %d\n", x);
        foo(x);  // pass a copy of x
        printf("In main, x = %d\n", x);
        bar(&x);  // pass the address of x so we can change it's contents
        printf("In main, x = %d\n", x);
    
    
        return 0;
    }
    Compiling and running it:
    Code:
    $ gcc -Wall -g -std=c99 params.c -o params
    
    $ ./params
    In main, x = 42
    In foo(), x = 17
    In main, x = 42
    In bar(), x = 17
    In main, x = 17

  12. #12
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by bobv View Post
    Any example? When you know how everything seems easy, but if you don't well... I know it's a u32 and what the values are but getting it there is another story, at leaset for me. The fact that the 4 bytes need to be in little endian format is another matter but I can deal w/that.
    Code:
         // IP converter
    #include <stdio.h>
    #include <string.h>
    
    unsigned long ConvertIP(char *IPString)
      {
        union t_cvt
          { unsigned long ip;
            unsigned char bv[4]; }
        cvt;
    
        sscanf(IPString,"%hhu.%hhu.%hhu.%hhu",&cvt.bv[0],&cvt.bv[1],&cvt.bv[2],&cvt.bv[3]);
    
        // for diagnostic only remove in use
        printf("%u %u %u %u\n\n",cvt.bv[0],cvt.bv[1],cvt.bv[2],cvt.bv[3]);
    
        return cvt.ip; }
    
    
    int main (void)
      { char ipstr[17];
        unsigned int ipaddr;
    
        printf("Enter an IP address : ");
        scanf("%s",ipstr);
     
        ipaddr = ConvertIP(ipstr);
    
        printf("\n %x\n\n",ipaddr);
    
        return 0; }
    To flip between little endian and big endian... simply reverse the assignment order in line 12
    Last edited by CommonTater; 11-22-2011 at 12:29 PM.

  13. #13
    Registered User
    Join Date
    Nov 2011
    Posts
    11
    CommonTater,

    Thanks for taking the time to put this together. Very nice solution but only if you can be assured the format of the input string is correct. Unfortunately I can't, as I said above the system doesn't support scanf nor does this solution seem to account for values > 255 or any incorrect IP address formatting issues (ex "192...23.5.77"). When I tried various inputs I always got a returned value with some funny values. I do filter the bytes coming in for only 0-9 & '.' chars but not much else so the string could be pretty incorrect. Probably need to go back to the drawing board and re-think a solution.

    Again thanks for your help, really appreciate you spending time on this.

    Regards,
    Bob

  14. #14
    Registered User
    Join Date
    Nov 2011
    Posts
    11
    anduril462, Thanks for your reply. I understand your code however this is not the problem I'm trying to solve. I'm trying to pass a string address (pointer) back through a member in the function call. Bob

  15. #15
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Does it support atoi() and strtok()?
    If it does you can tokenize the string on the dots and \0 at the end, extracting the value from each segment as you go.

    If it supports strchr() you can search for the dots and use atoi() to get the value one over from each dot.

    If any of the conversions fails just have your function return 0...

    The sscanf() solution is a good one because you can check the return value from sscanf() and confirm that it performed all 4 conversions correctly, if not have it return 0 (or some other impossible IP value)

    Code:
    if ( sscanf(IPString,"%hhu.%hhu.%hhu.%hhu",&cvt.bv[0],&cvt.bv[1],&cvt.bv[2],&cvt.bv[3]) != 4)
      return 0;
    Code:
        ipaddr = ConvertIP(ipstr);
        if( ! ipaddr )
          { printf("Invalid IP Address... don't do that again!\n\n");
            exit(0); }
    Last edited by CommonTater; 11-22-2011 at 01:12 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Function syntax to return a pointer...
    By tzuch in forum C Programming
    Replies: 1
    Last Post: 05-29-2008, 07:53 AM
  2. Have function return file pointer
    By krogz in forum C Programming
    Replies: 6
    Last Post: 05-03-2007, 08:56 PM
  3. how to make a function return a pointer
    By *DEAD* in forum C Programming
    Replies: 6
    Last Post: 01-14-2007, 07:14 PM
  4. Can a function return a pointer to itself?
    By King Mir in forum C Programming
    Replies: 4
    Last Post: 04-19-2006, 01:15 PM
  5. Function to return pointer to structure
    By Unregistered in forum C Programming
    Replies: 8
    Last Post: 06-25-2002, 06:10 AM