pavlos163
pavlos163

Reputation: 2890

C: Format %s expects argument of type char* in funny strings program

I am making a program to check for funny strings. To understand the exercise read this.

My code is here:

#define MAX_STR_LENGTH 10

char* reverse(char *str) {
    char *reversedStr = malloc(strlen(str));
    for (int i = 0; i < MAX_STR_LENGTH; i++) {
        for (int j = MAX_STR_LENGTH - 1; j > 0; j--) {
            reversedStr[i] = str[j];
        }
    }
    return reversedStr;
}

int isFunny(char *str, char *reversedStr) {
    for (int i = 1; i < MAX_STR_LENGTH; i++) {
        if (str[i] - str[i - 1] != reversedStr[i] - reversedStr[i - 1]) {
            return 0;
        }
    }
    return 1;
}

int main() {

    /* Enter your code here. Read input from STDIN. Print output to STDOUT */    
    int numberOfStrings;
    scanf("%i", &numberOfStrings);

    char **strings;
    for (int i = 0; i < numberOfStrings; i++) {
        scanf("%s", &strings[i]);
    }

    char **reversedStrings;
    for (int i = 0; i < numberOfStrings; i++) {
        reversedStrings[i] = reverse(strings[i]);
    }

    for (int i = 0; i < numberOfStrings; i++) {
        if (isFunny(strings[i], reversedStrings[i])) {
            printf("Funny\n");
        }
        printf("Not funny\n");
    }

    return 0;
}

The error I am getting is the following:

solution.c: In function 'main':
solution.c:35:9: warning: format '%s' expects argument of type 'char *', but argument 2 has type 'char **' [-Wformat=]
         scanf("%s", &strings[i]);

I don't understand why though.

My aim was to make an array of strings, called strings, and store there all the strings that I read. Why is strings[i] a char** ?

I would appreciate any help or tips.

Thanks!

Upvotes: 1

Views: 3209

Answers (1)

Iharob Al Asimi
Iharob Al Asimi

Reputation: 53006

Apparently you have a char * and you are passing it's address, which is wrong, scanf() wants a char pointer for each "%s" specifier, and the fix for your code is to use

char string[10];
scanf("%s", string);

the array automatically becomes a char pointer when passed to scanf() like above, but that's not enough.

Your array of char now as I suggest it is of fixed size, and even if it wasn't, using scanf() like that is dangerous, suppose that each array in the array of char arrays has 10 elements, then each string you want to read must have only 9 characters, you can instruct scanf() to stop reading when it already read 9 characters like this

scanf("%9s", strings[i]);

If you don't do this, then reading extra characters will be possible, but illegal, causing what's called undefined behavior.

If you want an array of strings, say of 5 strings with 9 characters each, then you can try

char strings[5][10];
int  i;
for (i = 0 ; i < 5 ; ++i)
    scanf("%9s", strings[i]);

Note: You need the & address of operator for example, when you pass an int value, because scanf() modifes the data pointed to by the passed pointer, so you need to make a pointer to the int variable where you want to scan the value, for that you use the & address of operator, since you pass a pointer containing the address of the variable.

Suggestion: Always check the return value of malloc(), it returns NULL on failure, and dereferencing a NULL poitner, is undefined behavior, you must be careful not to cause undefined behavior because it's too hard to debug.

Upvotes: 3

Related Questions