Carl
Carl

Reputation: 11

Returning an array from a C-function

I'm currently writing an application where I need a C-function to return an array. I've read that C-functions directly can't return arrays but pointers to arrays, anyhow I still don't get it to work. I'm sending a string with several numerical values that I have to put into an array.

My code looks like this, where the main function is:

int main() {
    char arr[3] = {0};
    char *str = "yaw22test242test232";
    foo(arr,3,str);

    printf("%d\n",arr[0]);

    return 0;
}

Where I want the foo function to return an array with the numbers 22, 242 and 232 on array positions 0, 1 and 2 respectively. The algorithm in the foo function works properly when used in the main program but not this way. Is there any way to work around this? What am I doing wrong? The foo function looks as follows:

void foo(char *buf, int count, char *str) {
    char *p = str;
    int k = 0;

    while (*p) { // While there are more characters to process...
        if (isdigit(*p)) { // Upon finding a digit, ...
            double val = strtod(p, &p); // Read a number, ...
            //printf("%f\n", val); // and print it.
            buf[1-count-k] = val;
            k++;
        } else { // Otherwise, move on to the next character.
            p++;
        }
    }
}

Upvotes: 0

Views: 109

Answers (3)

2501
2501

Reputation: 25752

Well you are going out of bounds here:

buf[1-count-k] = val;

perhaps you mean something like buf[k] = val; and a check if( k >= count ) to end the loop.

Since char *buf usually isn't able to represent values larger than 127, you should use an integer type large enough, or a double, otherwise the assignment buf[*] = val; from a type double to a type char, will cause undefined behavior.

Upvotes: 2

Filipe Gonçalves
Filipe Gonçalves

Reputation: 21213

It looks like you want to extract the numbers in the string as doubles, but you're trying to store them in a char array. This doesn't even compile.

So, first, use a proper buffer:

int main() {
    double arr[3] = {0};
    /* ... */
}

And update the parameter declaration in foo():

void foo(double *buf, int count,char *str) { ... }

And then fix this:

buf[1-count-k] = val;

You probably want something as simple as:

buf[k++] = val;

Finally, you may want to return k so that the caller has a chance to know how many numbers were written into the array. So, foo would look like this:

size_t foo(double *buf, int count,char *str) {
    char *p = str;
    size_t k = 0;

    while (*p) { // While there are more characters to process...
        if (isdigit(*p)) { // Upon finding a digit, ...
            double val = strtod(p, &p); // Read a number, ...
            //printf("%f\n", val); // and print it.
            buf[k++] = val;
        } else { // Otherwise, move on to the next character.
            p++;
        }
    }
    return k;
}

Note that the correct type to index an array is size_t, and not int. size_t is guaranteed to be wide enough to hold the size of any array, so if you want your code to work with arbitrarily long arrays, size_t should be used to index the array.

Upvotes: 0

Levi
Levi

Reputation: 1983

I would recommend using a vector-like structure instead of an array. There are many implementations of this already (see GLib lists for C). But if you want to 'roll your own', try something similar to this:

typedef struct
{
    char** data;
    int size;

} str_vector;

Where you can dynamically allocate a str_vector and its data member, and return this. I won't go into too much more detail as there is quite a few tutorials on this on the internet, which I am sure you can bring up in Google/Bing/Whatever in a manner of seconds :)

Upvotes: 0

Related Questions