Laxmi Kadariya
Laxmi Kadariya

Reputation: 1103

Returning of string pointer in C

I have a program with function which I supposed to provide the string as and argument and return the part of a string . Such that I want to return a pointer to the calling function as

int test_func(char *dest, const char *src)
  {
    int i,n,len_in_msg,j;
    char *rem_string;

    n=strlen(src);
    for (i = 0; i < n && src[i] != '\n'; i++)
      {
        dest = src+i;
      }
    printf("value of i  = %d ",i);

    dest = dest+2;
    printf("dest = %s", dest);
    return 1;
  }

Here I have a string as "100000\nis hhhhhhhh"; I want to separate "100000" and next string such that I want to return the later part as a pointer in dest to the calling function.

The dest is printed fine in the test_func() however it is not reflected in the calling function.

Even I tried calling as

int main()
{
    int msg_pointer = -1;
    int msg_length;
    char *test;
    char *test1;
    char *msg_full = "100000\nis  hhhhhhhh";
    //test = malloc(sizeof(char)*(100));

    msg_length = test_func(test, msg_full);

    printf("value of test = %s", test);
}

Also as &test but no luck. How can I achieve this??

Upvotes: 1

Views: 96

Answers (2)

David C. Rankin
David C. Rankin

Reputation: 84652

Since you are passing the address of test to test_func, within test_func, you must treat *dest as your pointer, not dest. For example, after passing &test through the parameter char **dest, you must allocate space for the value of dest not dest itself:

*dest = malloc (sizeof **dest * (len + 1));

That is what ouah meant when he stated:

/* change the body accordingly to new dest type */

I think your code should work following that change. If you run into additional issues, here is a slightly different variant on your approach that you can draw from:

#include <stdio.h>
#include <stdlib.h>

int test_func (char **dest, char *src, char delim);

int main (void)
{
    int msg_length = 0; 
    char *test = NULL;
    char *msg_full = "100000\nis  hhhhhhhh";

    msg_length = test_func (&test, msg_full, '\n');

    printf ("\n value of test = '%s' (%d chars)\n\n", test, msg_length);

    if (test) free (test);  /* free allocated memory */

    return 0;
}

/* copy characters in 's' following 'delim' to
   newly allocated block of memory in 'str' */
int test_func (char **dest, char *src, char delim)
{
    size_t len = 0;
    char *p = src;
    char *new = NULL;

    /* set p at start of second string, save pointer
       to start of second in new */
    while (*p) if (*p++ == delim) break;
    new = p;

    while (*p++) len++; /* length of new */

    *dest = malloc (sizeof **dest * (len + 1)); /* allocate */

    p = new;        /* set p to new    */
    new = *dest;    /* set new to dest */
    while (*p) { *new = *p++; new++; }  /* copy to *dest */

    return (int)len;
}

Output

$ ./bin/splitintwo

 value of test = 'is  hhhhhhhh' (12 chars)

One last note: (maybe 2), pay closer attention to your data types. (it matters). I have left the function return types as int as well as msg_length in your code, but they should really be unsigned int (or more properly size_t). Why? You cannot have a negative length. Get in the habit of matching your type to the information you are handling. This will become increasingly more important the further you progress in C.

main is a special function, with a required declaration. It is type 'int', meaning it must return a value (even if MS let's you get away without it). It should be declared with the required parameters (int argc, char **argv), even though for short snippets I don't always do that (evidenced by the code above). If you are not going to give the full declaration, at least explicitly tell the compiler what you are doing (e.g. int main (void)). While not technically correct, it is much cleaner than simply providing empty parens.

Upvotes: 0

ouah
ouah

Reputation: 145919

char *test;
/* ... */
msg_length = test_func(test,msg_full);

You are passing test an uninitialized pointer to test_func. If you want to modify a pointer object passed in parameter, use a pointer to a pointer:

int test_func(char **dest, const char *src)
{
   /* change the body accordingly to new dest type */
}

and:

 msg_length = test_func(&test,msg_full); 

Upvotes: 3

Related Questions