0

I'm having trouble working with strings in C. Here is my function which takes an array of strings and returns a randomly selected one. randint(int n) is a function which returns a random integer from 1 to n.

int rand_word(const char ARR[]) {
    int r = randint(sizeof(ARR));
    return(ARR[r]);
}

Here is my main():

int main() {
    const char *WORDS[3];

    WORDS[0] = "a";
    WORDS[1] = "b";
    WORDS[2] = "c";

    printf("%s", rand_word(WORDS));

    return 0;
}

I expected to see either "a", "b", or "c" printed.

[Error] cannot convert 'const char**' to 'const char*' for argument '1' to 'int rand_word(const char*)'

Essentially my confusion is between data types. What have I done wrong? Thanks.

mdnestor
  • 137
  • 2
  • 9
  • check carefully the types of the argument and the returned value type of your function. what is it supposed to take? What it is supposed to return? – Eugene Sh. Sep 27 '18 at 16:20
  • In a C function prototype, `char ARR[]` is really just syntactic sugar for `char *` because a function call converts an array into a pointer to the first element of the array. So `sizeof(ARR)` will have the same value as `sizeof(char *)`. You need to pass the actual length as a separate parameter. – Ian Abbott Sep 27 '18 at 16:25
  • If `randint(n)` returns a number from 1 to n, be aware that array index operations in C start from index 0, not index 1, so you would need to subtract 1 from the return value of `randint(n)` to get an index in the range 0 to n-1. – Ian Abbott Sep 27 '18 at 16:29
  • 1
    when you pass an array to a function it decays into a pointer with no information about the size of the original array. – AndersK Sep 27 '18 at 16:49

3 Answers3

1

Ignoring the fact that rand_word is 100% wrong lets just deal with the error message.

YOu have a function that is declared as taking at char array (char[]) as an argument. You are passing it and array of pointers to a char array. Thats not valid.

Change rand_word to accept char *ARR[]

now rand_word is wrong

a) sizeof (ARR) will always be 4 or 8. Its the size of a pointer. you cannot inspect a pointer to an array and determine the length of the array. Pass in a second argument with the length

b) The function returns an int. It should return a pointer to a string

pm100
  • 48,078
  • 23
  • 82
  • 145
1
  1. In a C function prototype, char ARR[] is really just syntactic sugar for char * because a function call converts an array into a pointer to the first element of the array. So sizeof(ARR) will have the same value as sizeof(char *). You need to pass the actual length as a separate parameter.

  2. If randint(n) returns a number from 1 to n, be aware that array index operations in C start from index 0, not index 1, so you would need to subtract 1 from the return value of randint(n) to get an index in the range 0 to n-1.

  3. Your rand_word function takes a pointer to the first element of an array of char and returns a single element of the array (a single char) converted to an int. But your caller passes the function a pointer to the first element of an array of const char * and expects it to return a const char * (judging from the use of the "%s" printf format specifier).

Putting that altogether, your rand_word function should look something like this:

const char *rand_word(int n, const char *ARR[])
{
    int r = randint(n) - 1; // randint returns number in range 1 to n
    return ARR[r];
}

Since your WORDS array has 3 elements, your printf call should be something like:

    printf("%s", rand_word(3, WORDS));

You could also use this macro to get the length of an array (doesn't work on pointers):

#define ARRAY_LEN(ARR) (sizeof (ARR) / sizeof (ARR)[0])

Then your printf call can be something like this:

    printf("%s", rand_word(ARRAY_LEN(WORDS), WORDS));
Ian Abbott
  • 15,083
  • 19
  • 33
  • this looks pretty neat. Can you please explain this arithmetic? (sizeof (ARR) / sizeof (ARR)[0]). – Tano Fotang Sep 27 '18 at 17:10
  • @fotang It is the size of the whole array (`(ARR)`) divided by the size of a single element (`(ARR)[0]`), giving the number of elements (i.e. the length) of the array. The parentheses around the macro parameter `ARR` are to avoid operator precedence problems when `ARR` expands to something other than a simple identifier. The `sizeof` operator itself doesn't need parentheses when operating on an object, so I didn't give it any. (However, `sizeof` does need parentheses when operating on a type, rather than an object.) – Ian Abbott Sep 28 '18 at 12:20
-1

First, you're providing a *char[] (or char[][]) for the parameter to rand_word() instead of a char[].

Then you return a char (ARR[r]). You should use %c instead of %s in your printf() statement because of this.

Either that or change const char ARR[] to const char* ARR[].

absoluteAquarian
  • 510
  • 3
  • 12