Thread: Function returning a string and assigning it to an Array.

  1. #1
    Registered User
    Join Date
    Sep 2007
    Posts
    69

    Function returning a string and assigning it to an Array.

    Hello,

    I have just recently began studying C programming. I use books (Im not yet in University) and its going great so far!

    I ran into a problem with one of my programs.

    Im trying to assign a string to an array. But not just any string but a string that is returned by a function.

    What I tried was:

    Code:
    /* The Function */
    char change_left_side(int x);
    
    /* Array */
    char left_digit[10];
    
    /* Start */
    int main()
    {
    left_digit = change_left_side(entered_number);
    }
    
    /* The actual function code */
    char change_left_side(int x)
    {
    return("Hello!");
    }
    This is of course just the required areas. I did not include all the variables, statements, etc. The whole program is a bit too big so I didn't want to encumber you. But the code is where the mistake is, so please help me.

    What is the best way to return a string and assign that returned string to an array?

    Thank you,

  2. #2
    Ex scientia vera
    Join Date
    Sep 2007
    Posts
    477
    Code:
    /* The Function */
    char change_left_side(int x);
    
    /* Array */
    char left_digit[10];
    
    /* Start */
    int main()
    {
    left_digit = change_left_side(entered_number);
    }
    
    /* The actual function code */
    char change_left_side(int x)
    {
    return("Hello!");
    }
    First of all, use "int main(void)"

    Using only int main() is the same as saying it isn't defined how many arguments main can take, but using void says it can't take any arguments. Just a good habit.

    Anyway, the fault with change_left_side lies in the fact that you can't return a string literal. Matter of fact, you can't return a string by value, eg you can't return the string as the characters.

    What you could do, however, would be to return a pointer, as follows:

    Code:
    /* .. some code .. */
    char *char change_left_side(int x)
    {
         unsigned char * szHello = malloc(20*sizeof(char));
    
         strncpy(szHello, "Hello", 5);
    
         return szHello;
    }
    If you were using C++, you could use the string class to return a string.

  3. #3
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    The real problem is that you're function's return type is char which is what you'd want if you tried to return a single character and also that you can't assign to arrays in the manner you are attempting. You want to return a string (null terminated char array) or rather the address of one so you need to change the return type to char*. There is nothing wrong with returning a string literal... the code returns the address in memory of the string literal. And this can be used by the calling code to copy the data into somewhere more usefull:

    Code:
    /* The Function */
    char* change_left_side(int x);
    
    /* Array */
    char left_digit[10];
    
    /* Start */
    int main()
    {
        /* Use strcpy to copy the returned string into your array, you can't assign like you were attemtping */
        strcpy(left_digit,change_left_side(entered_number));
    
        return 0;
    }
    
    /* The actual function code */
    char* change_left_side(int x)
    {
        return("Hello!");
    }
    Last edited by hk_mp5kpdw; 09-18-2007 at 01:26 PM.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  4. #4
    Registered User
    Join Date
    Sep 2007
    Posts
    69
    Thank you for all your help!

    I used hk_mp5kpdw's method and it worked like a charm. But Icedane's method more or less did what I needed as well. Is there a big difference between the two and is it a better programming style to practice Icedane's or hk_mp5kpdw's?

    Again, thanks for the help. I greatly appreciate it!

  5. #5
    Ex scientia vera
    Join Date
    Sep 2007
    Posts
    477
    Quote Originally Posted by +Azazel+ View Post
    Thank you for all your help!

    I used hk_mp5kpdw's method and it worked like a charm. But Icedane's method more or less did what I needed as well. Is there a big difference between the two and is it a better programming style to practice Icedane's or hk_mp5kpdw's?

    Again, thanks for the help. I greatly appreciate it!

    No, pretty much the exact same.

  6. #6
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    No, pretty much the exact same.
    No they're not... hk_mp5kpdw's method simply returns the address of a string literal then copies it onto the stack. Your method allocates memory on the heap and then copies the string literal onto it, you also don't free the memory you've allocated.

    You should also remain explicit with your pointers, considering you practically wrote:
    Code:
    char left_digit[20];
    
    left_digit = malloc(20*sizeof(char));
    Not to mention the possible difference in char signedness.

  7. #7
    Ex scientia vera
    Join Date
    Sep 2007
    Posts
    477
    Quote Originally Posted by zacs7 View Post
    No they're not... hk_mp5kpdw's method simply returns the address of a string literal then copies it onto the stack. Your method allocates memory on the heap and then copies the string literal onto it, you also don't free the memory you've allocated.

    You should also remain explicit with your pointers, considering you practically wrote:
    Code:
    char left_digit[20];
    
    left_digit = malloc(20*sizeof(char));
    Not to mention the possible difference in char signedness.
    It was an example, which is why I did not free the memory - Besides, in reality, were you to free the memory, you would not do it in the function - I just returned the pointer(Thus making the function exit, anyway), and then he could've done what would be needed with the memory allocated at the address, then he'd have to free it somewhere else.

    And no, look at the code again. I defined a pointer and allocated memory for it.

    But I admit to not knowing you could actually return a string literal - But it makes sense, anyway, as the literal is stored somewhere, just like any other data.

    EDIT: And oh, if you want to pedantic and say the two implementations were different because one is stored on the stack while the other is on the heap, you're right - But in the end, it simply returns a pointer to a string located somewhere in memory.
    Last edited by IceDane; 09-18-2007 at 03:57 PM.

  8. #8
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Dane, I agree with you for the most part but I would like to point out that the function call does have a pesky error:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    /* .. some code .. */
    char *change_left_side( int x )
    {
      unsigned char* szHello = malloc( x * sizeof( char ) );
    
      strncpy( szHello, "Hello", 5 );
    
      return szHello;
    }
    
    int main( void )
    {
      char *p = change_left_side( 20 );
      puts( p );
      free( p );
    
      return 0;
    }
    C:\Documents and Settings\Owner\cbproject\bar\windows\Debug_Build\b ar.exe
    Hello¢@

    puts kept printing bytes until it intereted something as zero. By definition, if the length argument is less than the length of the source string, a terminating zero will not be included in the copy.

  9. #9
    Ex scientia vera
    Join Date
    Sep 2007
    Posts
    477
    Quote Originally Posted by citizen View Post
    Dane, I agree with you for the most part but I would like to point out that the function call does have a pesky error:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    /* .. some code .. */
    char *change_left_side( int x )
    {
      unsigned char* szHello = malloc( x * sizeof( char ) );
    
      strncpy( szHello, "Hello", 5 );
    
      return szHello;
    }
    
    int main( void )
    {
      char *p = change_left_side( 20 );
      puts( p );
      free( p );
    
      return 0;
    }
    C:\Documents and Settings\Owner\cbproject\bar\windows\Debug_Build\b ar.exe
    Hello¢@

    puts kept printing bytes until it intereted something as zero. By definition, if the length argument is less than the length of the source string, a terminating zero will not be included in the copy.
    Yes yes, I didn't call memset to initialize it to zero, but the intention was merely to explain how he could return a pointer and that he couldn't return a string by value - I wasn't making code for him to copy-paste.

  10. #10
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Yeah but don't use that as an excuse to post broken stuff. Working code is often more instructional than broken code because people will run it to see what happens and it will work consistently.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Assigning a non null-terminated string
    By BattlePanic in forum C Programming
    Replies: 7
    Last Post: 05-04-2008, 10:02 PM
  2. assigning a string to a variable
    By xp5 in forum C Programming
    Replies: 12
    Last Post: 08-30-2007, 01:13 AM
  3. help with a source code..
    By venom424 in forum C++ Programming
    Replies: 8
    Last Post: 05-21-2004, 12:42 PM
  4. Assigning a String object to char*
    By The Dog in forum C++ Programming
    Replies: 13
    Last Post: 07-14-2002, 04:41 PM
  5. Passing string along function. Pointer.
    By Cheeze-It in forum C++ Programming
    Replies: 4
    Last Post: 06-23-2002, 07:23 PM