Thread: Pointer to string in functions

  1. #1
    Registered User
    Join Date
    Feb 2013
    Location
    Sweden
    Posts
    89

    Pointer to string in functions

    I'm sure this is a beginner's mistake, but exactly how should it be done?

    I made this example code to illustrate my question:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    
    int Right(char* In, char* Out, int Position){
        Out=&In[strlen(In)-Position];
        
        return 0;
    }
    
    
    int main(int argc, char *argv[])
    {
        char *a="Hello, world!", *b;
        
        puts(a);
        
        Right(a,b,3); // Total failure…
        puts(b);
        
        b=&a[strlen(a)-3]; // Works
        puts(b);
    
    
        return 0;
    }
    Well, I guess the code explains it all. I want b to be the last three characters of a using a function called ”Right”.

    Doing exactly the same thing without the function involved works fine. I just let b point to the third last character of a.

    Why does the function not work?

  2. #2
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    You're passing in a pointer, but you're passing it by value. This means you only change the local copy of out, the version in main is unchanged. To change a variable via a function, you need to pass a pointer to that variable. Thus, you need to pass a pointer to the pointer -- a pointer to out -- and dereference it in the function when you assign.

  3. #3
    Registered Superuser nul's Avatar
    Join Date
    Nov 2014
    Location
    Earth
    Posts
    53
    Perhaps return the address and assign it to "b" in the main function?

  4. #4
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    nul provides an excellent alternative, especially since the return value has no significance. It is the one I would use if I were to write such a function. However, I think it is critical for your understanding and skills that you implement it the original way as well.

  5. #5
    Registered User
    Join Date
    Feb 2013
    Location
    Sweden
    Posts
    89
    Quote Originally Posted by anduril462 View Post
    nul provides an excellent alternative,
    Yes, I have thought of that too, that's probably what I will do in the future when writing similar kinds of functions.

    Quote Originally Posted by anduril462 View Post
    especially since the return value has no significance.
    Well, don't pay too much attention to that, I only tried to come up with a simple example that illustrates my problem, an example that actually does something. I thought the return value thing would be for future enhancements, like error handling or something like that…

    Quote Originally Posted by anduril462 View Post
    It is the one I would use if I were to write such a function. However, I think it is critical for your understanding and skills that you implement it the original way as well.
    Yes, I totally agree.

    If I will ever need such a function in the future I would rather go for a ”b=Right(a,3)” syntax, and instead of moving a pointer, rather copy the characters from a to b to prevent unexpected results of b if a changes…

    But as I said, the above example is just that, an example, and I think I need to understand the mechanism behind it better, just like you said, so I'll experiment some more with it later.

    Thanks!

  6. #6
    Registered User
    Join Date
    Feb 2013
    Location
    Sweden
    Posts
    89
    So finally I had some time to deal with it. I came up with the following, that seems to work:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    
    int Right(char* In, char** Out, int Position){
        *Out=&In[strlen(In)-Position];
        
        return 0;
    }
    
    
    int main(int argc, char *argv[])
    {
        char *a="Hello, world!", *b;
        
        puts(a); // Hello world!
        
        Right(a,&b,6);
        puts(b); // world!
    
    
        return 0;
    }
    Last edited by guraknugen; 02-11-2015 at 02:50 PM.

  7. #7
    Registered User
    Join Date
    Feb 2013
    Location
    Sweden
    Posts
    89
    Though, if it all only was about writing a Right function, the Return version feels more straight forward to use and easier to understand, and the question asked in this thread is, of course, completely avoided…
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    
    char* Right(char* In, int Position){
        return &In[strlen(In)-Position];
    }
    
    
    int main(int argc, char *argv[])
    {
        char *a="Hello, world!", *b;
        
        puts(a); // Hello world!
        
        b=Right(a,6);
        puts(b); // world!
    
    
        return 0;
    }

  8. #8
    Registered User
    Join Date
    Feb 2013
    Location
    Sweden
    Posts
    89
    Quote Originally Posted by guraknugen View Post
    and instead of moving a pointer, rather copy the characters from a to b to prevent unexpected results of b if a changes…
    I don't know where that came from. Obviously I wrote before thinking… I think I was thinking about another solution I had, not discussed in this thread…

  9. #9
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Yep, that looks about right. You should consider checking that Position is sensible, or rather that strlen(In) - Position results in a sensible value.

    Since Out points somewhere inside In, if you modify *Out (b in main), you will modify In. Modifying the contents pointed to by b in main will modify the contents pointed to by a. Make copies of In or Out if you want to modify them while preserving the original.

    In your specific example, since a is just a pointer to a string literal, you can't modify it. String literals are constant, attempting to modify their contents results in undefined behavior (Question 11.33).

  10. #10
    Registered User
    Join Date
    Feb 2013
    Location
    Sweden
    Posts
    89
    Quote Originally Posted by anduril462 View Post
    Yep, that looks about right. You should consider checking that Position is sensible, or rather that strlen(In) - Position results in a sensible value.

    Since Out points somewhere inside In, if you modify *Out (b in main), you will modify In. Modifying the contents pointed to by b in main will modify the contents pointed to by a. Make copies of In or Out if you want to modify them while preserving the original.

    In your specific example, since a is just a pointer to a string literal, you can't modify it. String literals are constant, attempting to modify their contents results in undefined behavior (Question 11.33).
    Yes, you're right. I'll keep that in mind. Thanks.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Concentation of a pointer without string functions
    By Cdd101 in forum C Programming
    Replies: 8
    Last Post: 11-13-2013, 01:54 AM
  2. Replies: 5
    Last Post: 02-02-2013, 09:33 PM
  3. Replies: 7
    Last Post: 10-17-2012, 10:17 PM
  4. Question about functions of string vs char string
    By Robertjh12 in forum C++ Programming
    Replies: 2
    Last Post: 07-07-2011, 03:13 AM
  5. passing pointer to string between functions
    By liats80 in forum C Programming
    Replies: 4
    Last Post: 11-20-2007, 08:30 PM