Search code examples
cxcodecompiler-errorsxcode11

Passing 'void' to parameter of incompatible type 'const char *'?


When I run the below code, I get a "Passing 'void' to parameter of incompatible type 'const char *'" error on this line:

int result = strcmp(lowerCase(input), answers[i]);

The code that the error is in is:

for (int i = 0; i <= sizeof(questions); i++)
{
    printf("%s", questions[i]);
    scanf("%s", input);

    int result = strcmp(lowerCase(input), answers[i]);
    if (result == 0)
    {
        score++;
    }
}

and lowerCase is defined as:

void lowerCase(char s[]) {

   int c = 0;

   while (s[c] != '\0') {

      if (s[c] >= 'a' && s[c] <= 'z') {

          s[c] = s[c] + 32;

      }

      c++;
   }
}

The whole code is:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>             // strcmp() prototype is in here.
#include <ctype.h>

char *questions[3];
char *answers[3];

void fillQuestions(void);
void fillAnswers(void);

void lowerCase(char []);

int main(int argc, const char * argv[])
{
    fillQuestions();
    fillAnswers();

    char input[80];
    int score = 0;

    for (int i = 0; i <= sizeof(questions); i++)
    {
        printf("%s", questions[i]);
        scanf("%s", input);


        int result = strcmp(lowerCase(input), answers[i]);
        if (result == 0)
        {
            score++;
        }
    }
    printf("\n\tSCORE: %d\n\n", score);

    return 0;
}

void fillQuestions()
{
    questions[0] = "The famous basketball player Dr. J original name is what?";

}

void fillAnswers()
{
    answers[0] = "Julius Erving";

}

void lowerCase(char s[]) {

   int c = 0;

   while (s[c] != '\0') {

      if (s[c] >= 'a' && s[c] <= 'z') {

          s[c] = s[c] + 32;

      }

      c++;
   }

}

I am using XCode 11.3.


Solution

  • Compiler complaint

    You can't pass the value returned by a function that doesn't return a value onto another function (hence the error message about void and const char *).

    Because lowerCase() does not return a value (its return type is void), you can't do:

    strcmp(lowerCase(input), answers[i]);
    

    You'd use:

    lowerCase(input);
    int result = strcmp(input, answers[i]);
    

    Alternatively, revise lowerCase() so it returns a char * and end it with return s; (and then you don't need to change the call to strcmp()).


    Rewrite lowerCase()

    Since you include <ctype.h>, you could write:

    void lowerCase(char s[])
    {
       int c = 0;
       while (s[c] != '\0') {
          if (isupper((unsigned char)s[c])) {
              s[c] = tolower((unsigned char)s[c]);
          }
          c++;
       }
    }
    

    or:

    char *lowerCase(char s[])
    {
       for (int c = 0; s[c] != '\0'; c++)
          s[c] = tolower((unsigned char)s[c]);
       return s;
    }
    

    The casts are necessary in case plain char is a signed type. The functions from <ctype.h> take an int which is either EOF or the value of a character converted to unsigned char.

    It's not necessary to test whether the character is lower-case; the tolower() function leaves anything which is not upper-case unchanged — and additional advantage of using the functions.


    Other problems

    You have 3 elements in questions and answers, but you only initialize one element of each. When you loop to index 1, you get null pointers — hence address = 0x0 in the error message. You tried reading from a null pointer; crashes normally happen after you do that.

    Also, sizeof(questions) is almost certainly 24 — the number of bytes needed to store three 64-bit pointers. You need sizeof(questions) / sizeof(questions[0]) for the loop limit — if you add the extra two questions and answers.

    Because you convert the input to all lower-case, you'll never get an input that matches the answer (which is in mixed-case).

    The answer string is stored in a string literal. If you tried to modify the answer with lowerCase(), you'd get a crash because string literals are stored in read-only memory.