passing the address of an array of strings to a function

  • (2 Pages)
  • +
  • 1
  • 2

16 Replies - 1133 Views - Last Post: 10 October 2015 - 05:10 AM Rate Topic: -----

#1 COKEDUDE   User is offline

  • D.I.C Regular

Reputation: 2
  • View blog
  • Posts: 274
  • Joined: 01-February 10

passing the address of an array of strings to a function

Posted 08 October 2015 - 03:15 PM

I am trying to pass the address of strings_line_tokens to split_string. I would think I would need the "&" for the address then one of these methods would work.

static void split_string(const char *buffer, size_t buflen, char ***strings_line_tokens)
static void split_string(const char *buffer, size_t buflen, char **strings_line_tokens)
static void split_string(const char *buffer, size_t buflen, char **strings_line_tokens[])
static void split_string(const char *buffer, size_t buflen, char ***strings_line_tokens[])



Here is my declaration and where I try to pass the address to the function.

char *strings_line_tokens[503] = {0};
split_string(line, strlen(line)+1, &strings_line_tokens);


I keep getting some variation of this error.

warning: passing argument 3 of ‘split_string’ from incompatible pointer type
main.c:73: note: expected ‘char ***’ but argument is of type ‘char * (*)[503]’

Is This A Good Question/Topic? 0
  • +

Replies To: passing the address of an array of strings to a function

#2 Progammer   User is offline

  • D.I.C Head

Reputation: 1
  • View blog
  • Posts: 53
  • Joined: 28-February 13

Re: passing the address of an array of strings to a function

Posted 08 October 2015 - 03:26 PM

Here's something that should work:

since you want to pass the address of
char *x[503]   //used x as a short name

your function has to know it is fixed size strings (503), so it should be
static void split_string(const char *buffer, size_t buflen, char **strings_line_tokens[503])


in short you take the type you already defined x to be and add an asterisk because you want to pass the adress
Was This Post Helpful? 0
  • +
  • -

#3 COKEDUDE   User is offline

  • D.I.C Regular

Reputation: 2
  • View blog
  • Posts: 274
  • Joined: 01-February 10

Re: passing the address of an array of strings to a function

Posted 08 October 2015 - 03:58 PM

That didn't work.

 warning: passing argument 3 of ‘split_string’ from incompatible pointer type
main.c:74: note: expected ‘char ***’ but argument is of type ‘char * (*)[503]’

This post has been edited by Skydiver: 08 October 2015 - 07:33 PM
Reason for edit:: Removed unnecessary quote. No need to quote the post above yours.

Was This Post Helpful? 0
  • +
  • -

#4 baavgai   User is offline

  • Dreaming Coder
  • member icon


Reputation: 7419
  • View blog
  • Posts: 15,376
  • Joined: 16-October 07

Re: passing the address of an array of strings to a function

Posted 08 October 2015 - 04:17 PM

Just for fun, this would work:
#include<stdlib.h>
#include<stdio.h>
#include<string.h>

static void split_string(const char *buffer, size_t buflen, char *strings_line_tokens[503]);

int main() {
    char **p, *buffer = "Quoth the Raven,\nNevermore.";
    char *result[503];
    split_string(buffer, strlen(buffer), result);
    for(p = result; *p; p++) {
        printf("%s\n", *p);
    }
    return 0;
}

static void split_string(const char *buffer, size_t buflen, char *xs[503]) {
    /* your code here, but to test */
    xs[0] = "Edgar";
    xs[1] = "Alan";
    xs[2] = NULL;
}



Hard to see exactly what you're looking for with this. Also, one would think you'd want to pass back the size of the result. I stuck a NULL in there as a stop. Ideally, I'd want to dynamically allocate the result. And offer a way to release said result.

Hope this helps.
Was This Post Helpful? 0
  • +
  • -

#5 COKEDUDE   User is offline

  • D.I.C Regular

Reputation: 2
  • View blog
  • Posts: 274
  • Joined: 01-February 10

Re: passing the address of an array of strings to a function

Posted 08 October 2015 - 04:25 PM

Well with your example I want to fill result with some values. My understanding with pointers is if I do not pass the address of result then the values that got changed in split_string will be lost. Main() will not be able to see what is changed. Is that correct?

This post has been edited by Skydiver: 08 October 2015 - 07:56 PM
Reason for edit:: Removed unnecessary quote. No need to quote the post above yours.

Was This Post Helpful? 0
  • +
  • -

#6 Skydiver   User is offline

  • Code herder
  • member icon

Reputation: 6825
  • View blog
  • Posts: 23,203
  • Joined: 05-May 12

Re: passing the address of an array of strings to a function

Posted 08 October 2015 - 08:10 PM

No your understanding is incomplete.

You need to pass the address if you need an out parameter:
void setValue(int x, int *output)
{
    *output = x;
}

int main()
{
    int y = 2;
    printf("%d\n", y);
    setValue(12, &y);
    printf("%d\n", y);

    return 0;
}



You don't need to pass the address if you need to fill an array:
void setValues(int x, int count, int * arr)
{
    for(int i = 0; i < count; i++)
        arr[i] = x;
}

void dumpValues(int count; int * arr)
{
    for(int i = 0; i < count; i++)
        printf("%d ", arr[i]);
    printf("\n");
}

int main()
{
    int y[5] = { 0 };

    dumpArray(5, y);
    setValues(12, 5, y);
    dumpValues(5, y);

    return 0;
}



But if you need to allocate memory for the array and then set values, then you need to pass the address:
void allocateAndSetValues(int x, int count, int * arr)
{
    *arr = malloc(count * sizeof(int));
    if (!*arr)
        exit(-1);

    for(int i = 0; i < count; i++)
        arr[i] = x;
}

void dumpValues(int count; int * arr)
{
    for(int i = 0; i < count; i++)
        printf("%d ", arr[i]);
    printf("\n");
}

int main()
{
    int * y = 0;

    allocateAndSetValues(12, 5, &y);
    dumpValues(5, y);
    free(y);

    return 0;
}



Update: Don't stop here... See excellent corrections below!

This post has been edited by Skydiver: 09 October 2015 - 05:32 AM
Reason for edit:: Added update to keep following the thread.

Was This Post Helpful? 0
  • +
  • -

#7 jjl   User is offline

  • Engineer
  • member icon

Reputation: 1270
  • View blog
  • Posts: 4,998
  • Joined: 09-June 09

Re: passing the address of an array of strings to a function

Posted 08 October 2015 - 08:28 PM

@Skydiver I think you meant to a double pointer there.

void allocateAndSetValues(int x, int count, int ** arr)
{
    *arr = malloc(count * sizeof(int));
    if (!*arr)
        exit(-1);

    for(int i = 0; i < count; i++)
        arr[i] = x;
}


Was This Post Helpful? 1
  • +
  • -

#8 Skydiver   User is offline

  • Code herder
  • member icon

Reputation: 6825
  • View blog
  • Posts: 23,203
  • Joined: 05-May 12

Re: passing the address of an array of strings to a function

Posted 09 October 2015 - 04:00 AM

Yup. Thanks. Tough to type on phone with one hand while trying to get a baby to sleep in the other hand. I'll post update when I have both hands fee.
Was This Post Helpful? 0
  • +
  • -

#9 Salem_c   User is offline

  • void main'ers are DOOMED
  • member icon

Reputation: 2328
  • View blog
  • Posts: 4,437
  • Joined: 30-May 10

Re: passing the address of an array of strings to a function

Posted 09 October 2015 - 04:46 AM

jjl's answer needs parentheses.
void allocateAndSetValues(int x, int count, int ** arr)
{
    *arr = malloc(count * sizeof(int));
    if (!*arr)
        exit(-1);

    for(int i = 0; i < count; i++)
        (*arr)[i] = x;
}


It needs to subscript the pointer it points to, not itself.
Was This Post Helpful? 1
  • +
  • -

#10 Skydiver   User is offline

  • Code herder
  • member icon

Reputation: 6825
  • View blog
  • Posts: 23,203
  • Joined: 05-May 12

Re: passing the address of an array of strings to a function

Posted 09 October 2015 - 05:30 AM

Now that I have two hands free, this is what I normally do to save myself from the confusion:
void allocateAndSetValues(int x, int count, int ** arrOut)
{
    int * arr = malloc(count * sizeof(int));
    if (!arr)
        exit(-1);

    for(int i = 0; i < count; i++)
        arr[i] = x;

    *arrOut = arr;
}



Spoiler

Was This Post Helpful? 0
  • +
  • -

#11 COKEDUDE   User is offline

  • D.I.C Regular

Reputation: 2
  • View blog
  • Posts: 274
  • Joined: 01-February 10

Re: passing the address of an array of strings to a function

Posted 09 October 2015 - 05:18 PM

View PostSkydiver, on 08 October 2015 - 09:10 PM, said:

No your understanding is incomplete.

You need to pass the address if you need an out parameter:
void setValue(int x, int *output)
{
    *output = x;
}

int main()
{
    int y = 2;
    printf("%d\n", y);
    setValue(12, &y);
    printf("%d\n", y);

    return 0;
}



You don't need to pass the address if you need to fill an array:
void setValues(int x, int count, int * arr)
{
    for(int i = 0; i < count; i++)
        arr[i] = x;
}

void dumpValues(int count; int * arr)
{
    for(int i = 0; i < count; i++)
        printf("%d ", arr[i]);
    printf("\n");
}

int main()
{
    int y[5] = { 0 };

    dumpArray(5, y);
    setValues(12, 5, y);
    dumpValues(5, y);

    return 0;
}



But if you need to allocate memory for the array and then set values, then you need to pass the address:
void allocateAndSetValues(int x, int count, int * arr)
{
    *arr = malloc(count * sizeof(int));
    if (!*arr)
        exit(-1);

    for(int i = 0; i < count; i++)
        arr[i] = x;
}

void dumpValues(int count; int * arr)
{
    for(int i = 0; i < count; i++)
        printf("%d ", arr[i]);
    printf("\n");
}

int main()
{
    int * y = 0;

    allocateAndSetValues(12, 5, &y);
    dumpValues(5, y);
    free(y);

    return 0;
}



Update: Don't stop here... See excellent corrections below!


What do you mean by out parameter?

Aren't chars different than ints?

Don't I need to allocate memory with what I'm doing?

The only way I know how to do what I want to with strings_line_tokens is with malloc.
                //strings_line_tokens[l] = malloc(strlen(pch)+1);
                //strcpy(strings_line_tokens[l], pch);


This is the best example I have found for creating an array of strings (array of pointers to char if you wanna be technical).

http://stackoverflow...1095006/5425351

This post has been edited by COKEDUDE: 10 October 2015 - 04:14 AM

Was This Post Helpful? 0
  • +
  • -

#12 Skydiver   User is offline

  • Code herder
  • member icon

Reputation: 6825
  • View blog
  • Posts: 23,203
  • Joined: 05-May 12

Re: passing the address of an array of strings to a function

Posted 09 October 2015 - 06:48 PM

View PostCOKEDUDE, on 09 October 2015 - 08:18 PM, said:

What do you mean by out parameter?

Remember that in C, parameters are passed by value. If you want to have the effect of having parameter values changing, you'll need to pass by reference. You pass by reference by passing in a pointer to the value that you want changed.

View PostCOKEDUDE, on 09 October 2015 - 08:18 PM, said:

Aren't chars different than ints?

Only in terms of range values, and some of the simple shortcuts that language provides for us to make handling strings easier.

View PostCOKEDUDE, on 09 October 2015 - 08:18 PM, said:

Don't I need to allocate memory with what I'm doing?

I don't know. What are you doing inside your split_string() function? Can you share your function body?
Was This Post Helpful? 0
  • +
  • -

#13 COKEDUDE   User is offline

  • D.I.C Regular

Reputation: 2
  • View blog
  • Posts: 274
  • Joined: 01-February 10

Re: passing the address of an array of strings to a function

Posted 09 October 2015 - 10:25 PM

View PostSkydiver, on 09 October 2015 - 07:48 PM, said:

View PostCOKEDUDE, on 09 October 2015 - 08:18 PM, said:

What do you mean by out parameter?

Remember that in C, parameters are passed by value. If you want to have the effect of having parameter values changing, you'll need to pass by reference. You pass by reference by passing in a pointer to the value that you want changed.

View PostCOKEDUDE, on 09 October 2015 - 08:18 PM, said:

Aren't chars different than ints?

Only in terms of range values, and some of the simple shortcuts that language provides for us to make handling strings easier.

View PostCOKEDUDE, on 09 October 2015 - 08:18 PM, said:

Don't I need to allocate memory with what I'm doing?

I don't know. What are you doing inside your split_string() function? Can you share your function body?



I have been playing around with baavgai example. Its amazing how much things change just by just changing a few details. How does his example work without malloc? The purpose of my split_string() is to split string at different types of characters into separate strings (alphabetical, numerical, and punctuation). There is one small piece that I didn't want to mess with char *ptr[buflen]; that I have in my function. I split each piece of the array into alphabetical sections (a-z, A-z), numerical sections (0-9), and punctuation section(all the punctuation marks) then I append '\0' at the end because I want to be dealing with strings. I know my function is working.

Now I need a way to bring this back to my main function. I wanted to use strings_line_tokens[503] for this. It seemed to work fine just by setting the strings with the equal method. It seemed to get very buggy and unpredictable when I started to use pointers.

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

static void split_string(const char *buffer, size_t buflen, char *strings_line_tokens[503]);

int main() {
    char **p, *buffer = "Quoth the Raven,\nNevermore.";
    char *result[503];
    split_string(buffer, strlen(buffer), result);
    for(p = result; *p; p++) {
        printf("%s\n", *p);
    }
    return 0;
}

static void split_string(const char *buffer, size_t buflen, char *xs[503]) {
    /* your code here, but to test */
    char cookies[] = "cookies rock";
    //char echo[] = "e";
    char echo[] = "echooooooooooooo";
    char *c ="abcddf  ghjk  jhgfdfghjkhgfdfghj";
    char *x ="dfgchgjkllkhgfdgchbjabcddf  ghjk  jhgfdfghjkhgfdfghj";
    char *y ="xxyydfgchgjkllkhgfdgchbjabcdd";
    //*(c+1)="efghi";
    printf("boo1\n");
    xs[0] = c;
    printf("%s\n", xs[0]);
    printf("boo2\n");
    xs[1] = malloc(strlen(x)+1);
    strcpy(xs[1], x);
    printf("%s\n", xs[1]);
    printf("boo2\n");
    xs[2] = malloc(strlen(y)+1);
    strcpy(xs[2], y);
    printf("%s\n", xs[2]);
    printf("boo3\n");
    xs[3] = NULL;
    printf("---------------------------\n");
}



Results

boo1
abcddf  ghjk  jhgfdfghjkhgfdfghj
boo2
dfgchgjkllkhgfdgchbjabcddf  ghjk  jhgfdfghjkhgfdfghj
boo2
xxyydfgchgjkllkhgfdgchbjabcdd
boo3
---------------------------
abcddf  ghjk  jhgfdfghjkhgfdfghj
xxyydfgchgjkllkhgfdgchbjabcdd

This post has been edited by COKEDUDE: 09 October 2015 - 10:28 PM

Was This Post Helpful? 0
  • +
  • -

#14 baavgai   User is offline

  • Dreaming Coder
  • member icon


Reputation: 7419
  • View blog
  • Posts: 15,376
  • Joined: 16-October 07

Re: passing the address of an array of strings to a function

Posted 10 October 2015 - 03:47 AM

View PostCOKEDUDE, on 10 October 2015 - 01:25 AM, said:

How does his example work without malloc?


Heh, as Skydiver mentioned, C has some built in toys for strings. So, when you say "string value" that is a literal in your compiler. The program has to put it somewhere, right? It's essentially a constant and the pointer to it never, ever, changes. Knowing this, if you have a handle to that pointer, you can play with that.

When you have char *s = "foo"; you can move s about and even pass it, because it ain't going to change. However, if you should say char s[] = "foo"; you've done something different. You've defined s as s[4] and placed that literal string into the container. The container is ONLY available to you within the context it was declared.

Now, if you should have char buffer[500]; in a function, it MAY occupy the same location each time you call the function; but it may not.

My example was lazy, as I just wanted to show how char ** was already available to be updated. For a real string split function, you'll need some storage. It's interesting to note that the C builtin strtok is quite destructive, essentially throwing '\0' in the string it's supposed to search. This is understood, as avoiding malloc seemed like a good idea.
Was This Post Helpful? 0
  • +
  • -

#15 COKEDUDE   User is offline

  • D.I.C Regular

Reputation: 2
  • View blog
  • Posts: 274
  • Joined: 01-February 10

Re: passing the address of an array of strings to a function

Posted 10 October 2015 - 04:16 AM

This is my storage.

pch


//strings_line_tokens[l] = malloc(strlen(pch)+1);
//strcpy(strings_line_tokens[l], pch);

This post has been edited by COKEDUDE: 10 October 2015 - 04:16 AM

Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2