Why I'm getting unexpected result from strcmp function in c [closed] - c

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 11 days ago.
Improve this question
I have made a game and this is the last part when a player is required to type yes/no to paly again. But the result of this code is unexpected.
Code:
do{
setbuf(stdout, NULL);
printf("\nDo you want to play again(yes/no)");
scanf("%s", &yn);
}while(strcmp(yn, "yes")==0||strcmp(yn, "no")==0);
Result:
Do you want to play again(yes/no) no
Do you want to play again(yes/no) yes
Do you want to play again(yes/no) random
Do you want to play again(yes/no)
Its repeating over and over.
Can you fix this code?

strcmp(yn, "yes")==0||strcmp(yn, "no")==0 evaluates to true if yn is "yes" or "no" so that would explain the first two tests. You probably want:
do {
// ...
} while(!strcmp(yn, "yes"));
It does not explain the 3rd test "sjsbs". This probably means scanf("%s", &yn); failed. You should check the return value.
You did not tell us what yn is but it should be a array so leave out the '&'. It would be particular bad if it's a char yn (see buffer overflow later).
Whenever reading a string with scanf()**always** specify the maximum field width to avoid buffer overflow. If the input is smaller than what is being read byscanf()then a subsequent call would return that. Consider usingfgets()instead ofscanf(). You may still get partial input but with a sufficiently large buffer it will mostly just work. The other option is discard everything in the input buffer till you hit a newline or EOF (using getchar()` for instance).
char yn[3+1];
// ...
if(scanf("%3s", yn) != 1) {
printf("scanf failed\n");
break;
}
Use constants instead of magic values especially related ones 3+1 and 3. You seem new at this so don't worry about this quite yet but this is how you would fix that:
#define YN_LEN 3
#define str(s) str2(s)
#define str2(s) #s
// ...
char YN[YN_LEN+1];
// ...
if(scanf("%" str(YN_LEN) "s", yn) != 1) {
// ...
I encourage you to format your code consistently (do { and } while should be at the same level, and I prefer compact code so more of it fits on the screen t a time (i.e. remove all those blank lines).

Related

Would you please explain why I am getting error in this testcase 99? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 11 months ago.
Improve this question
https://codeforces.com/contest/61/problem/A
Here in the testcase 99 of this I am experiencing an error which I am not getting in codeblocks. What I have identified is, after printing the needed output correctly, some 1s are being printed. I am not getting the fact why these 1s are being printed.
Here is my code:
#include<stdio.h>
#include<string.h>
int main()
{
char x[100],y[100];
scanf("%s%s",&x,&y);
for(int i=0;i<strlen(x);i++)
{
if(x[i]==y[i])
{
printf("0");
}
else
{
printf("1");
}
}
return 0;
}
Image: Error in testcase 99
That use of scanf is dangerous. It can lead to a buffer-overflow, that will produce undefined behaviour (behaviour may be different on different platforms, or even each time that you run the program).
Turn on compiler warnings. Use a good static analysis tool, or better use a safer language such as golang. Then use scanf format strings that prevent buffer overrun. On gcc the option -Wall will turn on this warning. You may also want to turn on some other warnings, or turn up the level to be more strict (especially for new code).
You have some issues in your code:
char x[100],y[100];
scanf("%s%s",&x,&y);
The type of second and third argument for scanf is not correct. They may have correct value, but strictly speaking they are wrong.
You need a char* but you provide a char (*)[]. You should just use x,y without the &.
Also you do not take care about potential buffer overflows.
To avoid buffer overflows, you should add a length limit to your format specifier. It must be one less than the size of your arrays.
Also you are required to deal with numbers up to 100 digits. That does not fit into your buffers.
If you need to handle strings of length 100, your arrays must have size 101.
You don't do this. If you get a string that is too long for one of your arrays, you will probably overflow into the next buffer losing the terminator byte.
That said, the 2 lines above should look like this:
char x[101],y[101];
scanf("%100s%100s", x, y);
Additionally you should always check return value of scanf and other IO functions.
To improve performance a bit, you should also not call strlen in each iteration of the loop. Instead you should call it once before the loop and store the value to use it in the loop condition.

Using strcmp in a while condition to break the loop [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I need to write a program where the program needs to loop and get input from the user. In order to break the loop, the user will need to type exit on the keyboard.
The following is my code:
int main()
{
char input[100];
char terminate[100]="$exit";
//if input does not equals to terminate keep asking user for input
while(strcmp(input, terminate)!=0)
{
printf("$");
fgets(input,100,stdin);
}//otherwise, exit the program
}
I tried testing the code above but it keeps on looping even after typing the word exit. Your assistance is greatly appreciated. :)
fgets will read the EOL character which will be included in the final string.
You may use strncmp to just use the characters from "terminate": strncmp(input, terminate, strlen(terminate).
There are two (and possibly three) problems in your code as you show it:
The first, which is very serious, is that you use input before it's initialized. That means the contents of the array is indeterminate (and could be seen as "random" or "garbage"). That will very likely lead to undefined behavior when you use it in strcmp because it's not a proper null-terminated string.
The second problem is that fgets adds the ending newline in the buffer, so unless you remove it or add a newline in the string you compare with the strings will never be equal.
You can easily remove the newline from the input string by using the strcspn function:
input[strcspn(input, "\n")] = 0;
The possible third problem is that you seem to be adding the prompt $ in the string you compare. Unless the user actually writes the $ in the input given, it will not be part of the input.
You also don't need to use as many characters for the terminate array. Instead let the compiler decide the proper amount:
char terminate[] = "exit"; // The size of the array will be 5, including null-terminator
Figured it out. Here is my solution:
while(strncmp(input, terminate,4)!=0)
{
printf("$");
fgets(input,100,stdin);
}
use strncmp instead of strcmp.

how to check if a variable is equal to a word [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 7 years ago.
Improve this question
I have this code. I want that when the user writes yes the program will print OK.
However, the program writes
"yes is undeclared".
How can I make the program treat to 'yes' as a word and not as a variable?
char a = ' ';
scanf("%c",&a);
if(a == yes)
{
printf("OK");
}
First thing first, 'yes' is not a word (sting, if you mean that), "yes" is.
That said, you're way out of league for the idea. One possible implementation can look like
First, you need to define an array for the input, like char a[12] = "no"; because you need to store more than one character as per your need. (the size used here is just indicative).
Scan the user input using scanf(), like scanf("%11s", a);
Use strcmp() from string.h, for comparison, like if (!strcmp(a, "yes")).
Another possible implementation could make use of an enum of "YES" and "no", take the user choice as integer and make use of the good old == comparison operator.
There are numerous problems in your code.
First of all, you declare a as a char (character) which means you can't compare it to "yes" because that's a string, or char array because this is C.
It's composed of 4 characters (3 for the text, 1 for the \0; in C "strings" are null-terminated so there has to be an ending character).
Declare your variable and read it like this:
#include <string.h> //you need this for string comparison
char a[10]; //arbitrary size, just make sure it's big enough for the input
scanf("%s", a);
//OR
fgets(a, sizeof(a), stdin); //use fgets if you need to read more than one word, scanf stops reading at whitespace
//don't use == to compare strings
if (!strcmp(a, "yes")){ //use quotes to delimit "words"
printf("OK\n");
}

Forcing users to write input in a specific format [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 8 years ago.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Improve this question
i'm making a program in C. that keeps track of items in a warehouse.
and i want to force the user to include at least one number!
example dvd1, dvd2. hello1, hello20
is there a way to do this?
at this moment i am using scanf.
and i want the product code to have the requirement format of xx-xxx-xxx were x are numbers.
i'm using scanf ( %[0-9-]s
Mvh Anton!
scanf doesn't work like that, it doesn't have in-depth validation.
You need to read the input into a char array, then loop through each character and see if it is a digit.
Something like this (untested):
char buffer[1000];
int i = 0, hasDigit = 0;
scanf("%s", buffer);
while (i < sizeof(buffer) && buffer[i] != 0 && !hasDigit)
{
hasDigit = isdigit(buffer[i]);
i++;
}
// if hasDigit is 0, there are no digits
Note: scanf isn't great, since if you enter more characters than fit in the buffer it can cause a buffer overflow. It is better to use fgets(buffer, sizeof(buffer), stdin);
Read the input and you can iterate through as in This SO question. You can check to see if chars match the input you want pretty easily from that point on.

I am trying to do a program that picks a vowel from the user input [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char *v= "a";
char *o='e';
char * w='i';
char *e='o';
char *l='u';
char *u[1];
printf ("please enter your character\n");
scanf ("%c",& u);
if (u == v){
puts("the character is it a vowel\n");
}
if (u == o) {
puts("the character is it a vowel\n");
}
else
puts("the character is a constant\n");
system("PAUSE");
return 0;
}
i need help in getting the right answer in finding a vowel from the user input.
First of all, shame on you for ignoring all of the compiler warnings you certainly received. They are there to help prevent you from doing "stupid things."
And why all this nonsense? This is the first of the "stupid things" the compiler is trying to tell you about.
char *v= "a";
char *o='e'; // invalid - Initializing a pointer to a constant 'e' (101).
char * w='i'; // invalid
char *e='o'; // invalid
char *l='u'; // invalid
Are you familiar with how pointers work? If not, I suggest you do some reading and understand them.
The first line makes sense - you're making a string and pointing char* v to that string.
But there's really no point in using pointer for those characters - or even variables at all. Just compare them directly:
char my_character;
if (my_character == 'a') {
// do something
}
And as for reading the character, again, you're using pointers when it doesn't make sense:
char *u[1]; // why?
Instead, just define a single char variable. Now, go look at the documentation for scanf. Giving it a format string of "%c" means, "I want to read just one character". Then, you need to tell where scanf to put it. You do this by passing it the "address of" the variable you want to store it in. You do this with (unsurprisingly!) the address of operator &.
char input_character;
scanf("%c", &input_character);
Armed with this information, you should be able to complete your work. Next, I suggest you look into the switch statement.
Finally, you must use consistent formatting (indentation, spacing) and use meaningful variable names, if you have any desire of ever being taken seriously as a programmer. Spelling out "vowel" for your pointless variables may be "cute" but it's total nonsense.
Most importantly, you should never write a single line of code, unless you understand exactly what it does. If you do this, then do not go asking anyone for help (especially not StackOverflow). If you can't explain what your code is doing (or at least what you think it's supposed to do), then you don't deserve for your program to work.

Resources