1

I'm creating a program where typing anything other than Small, small, Large, large will re-prompt the user for input but what happens is that it only accepts "Large" but not the other correct inputs. output

#include <stdio.h>
#include <string.h>
int main()
{
    char drinksize[5];
    do
        {
            printf("\nEnter Drink Size (Small or Large): ");
            scanf("%s", drinksize);
            if(strcmp(drinksize, "Small") == 1 || strcmp(drinksize, "small") == 1 || strcmp(drinksize, "Large") == 1 || strcmp(drinksize, "large") == 1)
            {
                printf("Incorrect item number! Please try again.");
            }
        }
        while (strcmp(drinksize, "Small") == 1 || strcmp(drinksize, "small") == 1 || strcmp(drinksize, "Large") == 1 || strcmp(drinksize, "large") == 1);
}
Jian
  • 13
  • 3
  • More importantly, your use of scanf is buggy. – Yunnosch Jun 20 '22 at 06:24
  • `strcmp` return a value > 0 (e.g. 1) if the 1st string is "larger" (lexicographycally) than the 2nd. I don't think that's what you want. – wohlstad Jun 20 '22 at 06:26
  • 2
    `strcmp` returns 0 when two strings are equal. Comparing with `1` is almost completely meaningless, since a return value of `1` can mean different things for different library implementations. – user3386109 Jun 20 '22 at 06:27
  • You need to study the basics of strings such as this: [How should character arrays be used as strings?](https://stackoverflow.com/questions/58526131/how-should-character-arrays-be-used-as-strings) – Lundin Jun 20 '22 at 07:43

1 Answers1

0

Yes.

Quoting from spec (e.g. https://en.cppreference.com/w/c/string/byte/strcmp ):

Return value Negative value if lhs appears before rhs in lexicographical order.
Zero if lhs and rhs compare equal.
Positive value if lhs appears after rhs in lexicographical order.

It does not say "1" anywhere and I suspect you want 0 for this.

Also your scanf() is risky, vulnerable to attacks and even incorrect for exactly the inputs you expect. You need more buffer even for predicted inputs like "Small" or "small".

Yunnosch
  • 26,130
  • 9
  • 42
  • 54
  • I modified my code to this: https://imgur.com/a/y7DQxUR so it looks for 0 instead of looking for 1 but it still doesn't work – Jian Jun 20 '22 at 06:38
  • I have answered the question on this page. Please ask a new one on the specifc way which the changed code ([mre] instead of picture of text please) does not act as expected. – Yunnosch Jun 20 '22 at 06:45
  • But I suspect you want `&&` instead of `||`. There is a duplicate question on that. https://stackoverflow.com/questions/69458480/how-to-compare-char-array-with-char-in-c-language/69458744 The question you would ask on the changed code would be closed as duplicate of that one. – Yunnosch Jun 20 '22 at 06:46
  • @Jian Your changed code is still risky. You must provide length of the string, not size of buffer: `%5s`. – Gerhardh Jun 20 '22 at 07:40
  • 1
    @Jian you also inverted the sub expressions using `!`. That is wrong. That means you ask if the string is not "small" or not "Small" or ... which must always be true because it can only be same as one of your strings, making all other wrong. – Gerhardh Jun 20 '22 at 07:42
  • 1
    A string `"small"` cannot be stored inside `char drinksize[5];`, simple as that. It's not really about the use of scanf but about string newbie 101. – Lundin Jun 20 '22 at 07:44
  • @Gerhardh I disagree, inverting with `!` is correct, combining with `||` is wrong. – Yunnosch Jun 20 '22 at 08:59
  • @Lundin Scanning an expected "small" into a 5 member `char` array without size protection is incorrect useage of `scanf()`. It is also a symptom of generally having trouble with the "pseudo" strings in C - true. – Yunnosch Jun 20 '22 at 09:02
  • @Yunnosch there are multiple ways to make it correct. Inverting the whole expression instead of each subexpression would also be OK. As that was part of the change introduced, I mentioned it. – Gerhardh Jun 20 '22 at 09:19
  • @Gerhardh True. Inverting the whole expression is an option (just my habits to go via andnot instead of notor); personal preference made me miss that. – Yunnosch Jun 20 '22 at 10:55