Hi, I'm learning C and I was trying to print this program using if-else statement:

void main()
{
    char* opinions;
    printf("What do you think of me?");
    scanf("%s",&opinions);
    if (opinions="Ugly")
    {
        printf("Huh, I'm way more beautiful than your heart");
    }
    else if (opinions="Blacksheep")
    {
        printf("Sometimes Blacksheeps end up shining the most!");
    }
    else if (opinions="Self-Centered")
    {
        printf("Mark time, I've planned to share the most during my whole life");
    }
    else
    {printf("You just know less then 1% about me");
    }
}

But when I run it, I get the output of "if" state. The "elseif" and "else" statements are not working. What's the issue and how to fix it?

Using "void main()" for the main function has been deprecated for, oh, over 30 years. Standard C requires a return type of int from the main function. People keep using it because compilers let it slide, and vice versa.

You seem to have left out #include <stdio.h> at the top. You'll also need #include <string.h> to fix the logic problem.

The logic problems I see are:

  1. You are using a pointer for opinions when an array is needed. Declare opinions as "char opinions[256];" instead. That will get you farther along.

  2. The = operator is assignment, not comparison for equality. You can compare numbers with the == operator, but not strings. Use strcmp() from for comparing strings. strcmp(string1, string2) returns 0 if the two strings are the same, a positive number if the first string is greater than the second, or a negative number if the first string is less than the second.

  3. A scanf() for a string should specify a maximim length in the format (one less than the array size) and you do not use & with an array argument. Make that scanf("%255s", opinions);.

  4. If you fix the main line to read "int main(void)" as it should, then you'll need a "return 0;" line at the end of main.

Here's how I updated your source:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
    char opinions[256];
    printf("What do you think of me?");
    scanf("%255s", opinions);
    if (0 == strcmp(opinions, "Ugly"))
    {
        printf("Huh, I'm way more beautiful than your heart");
    }
    else if (0 == strcmp(opinions, "Blacksheep"))
    {
        printf("Sometimes Blacksheeps end up shining the most!");
    }
    else if (0 == strcmp(opinions, "Self-Centered"))
    {
        printf("Mark time, I've planned to share the most during my whole life");
    }
    else
    {
        printf("You just know less then 1% about me");
    }
    return 0;
}

Get that running, and then you can start thinking about how to handle upper/lower case mismatches (What happens if the user enters "blacksheep" instead of "Blacksheep") or multiple words separated by spaces (like "black sheep".)

commented: Could you please explain to me how "int main()" and "int main(void)" differ? +0

Husoski: using

scanf("%255s", opinions);

accept space\tab too?

commented: No, %s scanning stops on any whitespace, not just a newline. Use %255[^\n] to include any character except a newline. +0

Comparing null terminated char arrays is:

#include <string.h>
int strcmp(const char *s1, const char *s2);

but for known length unterminated strings:

   #include <string.h>
   int memcmp(const void *s1, const void *s2, size_t n);

Both return an integer less than, equal to, or greater than zero if s1 is found, respectively, to be less than, to match, or be greater than the first n bytes of s2. Beware: other comparisons do other things, useful in other cases! For instance, for case insensitive null term string comparison:

   #include <strings.h>

   int strcasecmp(const char *s1, const char *s2);

Sappie asked a question in a comment to my earlier answer and I can't figure out how to respond directly to a comment so here's my answer.

The question asks the difference betwee int main() and int main(void).

The short answer is that both declare a function returning an int, but int main(void) explicity says that the function takes no arguments, while int main() says noththing at all about arguments.

tl;dr: This odd usage is due to the fact that in Dennis Ritchie's original C language there was no way to declare parameter types. Every function definition looked like some_type function_name();, and functions returning an int usually weren't declared at all. The compiler would assume that any function not previously defined or declared, was a function returning an int; and if no such function were defined later in the source code, then it was defined as an external int-returning function, to be found by the linker.

By the time the first C standard (ANSI C, 1989) was being developed, the original syntax had been in wide use for about a decade, so the old syntax couldn't be made illegal. Too many programs were using it. The void keyword was added to provide an explicit way to say "nothing is expected" as the return type or argument list of a function. (The void keyword was also used as a placeholder for an unknown type in pointer declarations.)

That same standard (C89) also made the int the standard return type from main, and specified that any implementation must allow for either of two declarations to be valid: int main(void){...} --or-- int main(int argc, char **argv) {...}

An implementation can allow other declarations (most OSes will pass an environment pointer as a 3rd argument), but those two must be allowed. And that is why I use int main(void) in any portable program (or the 2nd form if I use command line arguments).

commented: Good explanation. Let hope they do this from now on. +15

Husoski: "No, %s scanning stops on any whitespace, not just a newline. Use %255[^\n] to include any character except a newline."
the '[^\n]' is ANSI or GNU compatible? and strange, in these case, you don't use 's'.
Note: i'm sorry, but i can't vote your comment

Husoski gave the most comprehensive answer. Let me just add why the first if clause always triggered instead of the others.

As pointed out, the “=“ is the assignment operator. As it happens, the assignment statement not only causes the assignment to occur, but it also has a value like any expression. The value of the statement X=Y evaluates to the value that was assigned (i.e. whatever Y is). Side note: that’s why you can assign one value to multiple variables like this: a=b=c=1 (it is right associative, so 1 is assigned to c and the value of that expression is 1 which is assigned to b and the value of that expression is 1 which is assigned to a).

Since you put the assignment statement into a logical expression of an if-statement, any assignment of a value other than zero is treated as True (only a zero or null pointer assignment gets treated as False). You assigned a string’s pointer value to a variable and the pointer value was not null because it pointed to the string’s address in memory. So no matter what you entered the first if clause evaluated as True (and so would all the other else-if clauses if you could have gotten past the prior ones).

C is notorious for marching on without giving you any hint of an error because of the default assumptions it makes when you code something wrong.

Hope this provides a little forensic insight that will help you as you continue coding in C. I love C, but it doesn’t always love me back.

commented: Reply = Glorious; +15