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.

4
  • 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? Commented Sep 27, 2018 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. Commented Sep 27, 2018 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. Commented Sep 27, 2018 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. Commented Sep 27, 2018 at 16:49

3 Answers 3

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

Sign up to request clarification or add additional context in comments.

Comments

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));

2 Comments

this looks pretty neat. Can you please explain this arithmetic? (sizeof (ARR) / sizeof (ARR)[0]).
@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.)
-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[].

2 Comments

Not my DV, but your notation *char[] is peculiar and not C. Maybe you had char *[] in mind?
that may be the case. i've always used *char[] instead of char*[]. i.e. char *thing[] instead of char thing*[]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.