loop does not terminate [duplicate] - c

This question already has answers here:
Why is "a" != "a" in C?
(11 answers)
Closed 8 years ago.
I have a code below that asks if the user wants to retry or not. If the user enters no, the program will terminate. My code doesn't work and the loop still runs even if the input is "no"
#include<stdio.h>
int main()
{
char x[5];
do
{
printf("would you like to try again?");
scanf("%s",&x);
}
while(x != "no");
getch(); return 0;
}
I've tried adding a space in the scanf just like for characters to consume the newline but it also doesn't work. sorry for a very noob question.

You should use strcmp() to compare strings.
do { ... } while (strcmp(x, "no") != 0);

The issue of comparing an char array has been addressed by other answers and comments. There is another possible problem with an array of 5 elements being overrun by an input of "Yes, I would like to try again." Using %4s will limit scanf. Another option would be to use fgets ( x, sizeof ( x), stdin); fgets will include the newline so the comparison would be to "no\n" instead of "no".
#include<stdio.h>
#include<string.h>
int main()
{
char x[5];
do
{
printf("would you like to try again?");
scanf("%4s",x); // %4s prevent overrun. x is array, no need for &
}
while( strcmp ( x, "no") != 0);
getchar();
return 0;
}

You can't compare two strings by using !=, since the value of x is actually the memory address of your string.
You must include string.h and use the strcmp() function. (Take a look at the doc.)

x is just stand for the base address of the array while "no" is just stand for the address of the literal string [no\0]. So x != "no" is comparing two addresses which is always false.
You should use strcmp in the standard C lib.

Your problem is at the condition of the while loop. x is an array that contains characters. Using the x!="no" you are checking the base address of the array (to be more specific when you drop the brackets the compiler translate that as a pointer that points at the array x at the cell x[0,0]).
So the best solution and the easiest one to your problem is to use the strcmp function. The strcmp stands for string compare. This function compares character by character between two strings using the ascii code. The strcmp function returns zero only if the two strings are the same.So at your case you should use something like:
while(strcmp(x,"no")!=0){
....

Related

Trouble with C else, if and scanf

I am new to C and I'm making my first "decent" program. I am facing trouble with my code.
char username[] = "root";
char usernametry[10];
scanf("%s",usernametry);
if (usernametry == username)
{
printf("Welcome ROOT user\n");
}
else
{
printf("Try again\n");
}
Whenever I execute my program, everything works; however, when I try to log in and type root as the username, it returns Try again. Can someone suggest why this is happening? I am very new to C so I apologize for my lack of C knowledge.
usernametry and username are arrays of type char. When you do usernametry == username, you are not comparing if two strings are equal, you are comparing the memory address of the first char in usernametry with the memory address of the first char in username. In order to compare if two strings are equal, you should use strcmp. Also, consider replacing %s in your scanf with %9s so that usernametry will never exceed 9 chars (which would have been a buffer overflow, as the 10th char needs to be '\0', the null character, which is used to terminate C-style strings).
You can't compare strings using ==, this is not a that-high-level-language. See strcmp() for comparing strings.
Incidentally, what if someone enters a name longer than 10 characters? You're drifting towards a buffer overflow bug in your code ;-)
use strcmp() functions to compare 2 strings instead of ==
use of == is wrong because in this case you compare address of usernametry and username and of course they are always differents.
if(strcmp(usernametry, username) == 0) // return 0 if equal !=0 if not equal
Use strcmp to compare two strings:
if(!strcmp(usernametry,username))
Your variables are not the same pointer.
Replace by:
if (!strcmp(usernametry, username))

gets() function string behaviour [duplicate]

This question already has answers here:
How do I properly compare strings in C?
(10 answers)
Closed 8 years ago.
I have a small problem using gets function and a simple if expression.
It has to check whether the input is correct or no, in this case should be: !S
char checkCommand[5];
gets(checkCommand);
if(checkCommand=="!S")....;
else puts("Invalid command!");
How come I never end up to get true value for the expression,
even if I type !S ? Thanks for all answers!
Because you do not compare strings in C like this: (checkCommand=="!S")
To compare strings, you should use strcmp or strncmp or memcmp functions.
Example: In your case you use it like this:
if (strncmp(checkCommand, "!S", 5) == 0)
To read more about these functions, visit this link and similar.
You should also have noticed a warning "gets is dangerous..." something like this. You should avoid using gets and use fgets instead. The reason is well explained by Chris Jester-Young in his answer.
C has no strings; it has character pointers, and == simply compares the pointers. Use strcmp or strcasecmp (if your system has that) to compare strings. Note that strcmp returns 0 when the strings compare equally.
Also, avoid using gets. If a user enters a string longer than 4 characters (in your case), other parts of your memory will start getting scribbled on. Instead, prefer to use fgets, which allows you to specify the size of your input buffer.
You must use strcmp() function to compare two strings in c
int ret;
ret=strcmp(checkCommand,"!s");
if(ret!=0)
{
printf("Invalid Command");
}
Replace if(checkCommand=="!S") -> if(!strcmp(checkcommand,"!S"))

C programming: IF statements

I need help on a problem on C programming. I was wondering if there is a way to have a user input a word to the console and it would display whatever you program it to. Heres a example of what I want to do
int Choice;
int Energy = 100;
printf ("Type 2817!\n");
scanf ("%s", &Choice);
if(Choice == 2817)
{
printf ("You have started the game\n\n\n\n\n\n\n\n\n\n\n");
}
else if(Choice == "Energy") //This isnt working in my compiler.
//Apparently the == sign is the underlined error
{
printf("%d", Energy);
}
So far I can only type numbers but I want to be able to type words and be able to use a command. SO basically I want to be able to type "Energy" and it will show the amount of energy you have (printf ("%d", Energy)
Please help,
Thank you for reading.
You have enter wrong datatype when comparing the choice (int type) with a string text. In C/C++ unlike dynamic programming language, you cannot compare int with strings without properly converting either of them. You use strcpy for comparing string and == for comparing int.
Then your programming will run.
I'm not sure what your program is trying to do, but let me concentrate on the few obviously incorrect lines.
First, in
int Choice;
scanf ("%s", &Choice);
you have the wrong type for Choice: it is "int" whereas it should be a static array of char (let's say char Choice[32]). In this case you also have to remove the "&" before "Choice" in the scant, so that the code becomes:
char Choice[32];
scanf ("%s", Choice);
Moreover, in
else if(Choice == "Energy") //This isnt working in my compiler.
you are trying to compare two strings with the operator "==". This does not work in C. You should use the function "strcmp" the following way:
#include<string.h>
[...]
else if(strcmp(Choice, "Energy")==0)
You'd even better use the following to prevent any buffer overflow
else if(strncmp(Choice, "Energy", 32)==0)
(replace 32 with the maximum number of elements in Choice)
Edit Note that you should change the first comparison too from
if(Choice == 2817)
to
if(strncmp(Choice, "2817", 32))
because Choice is not an int anymore...
The best way to approach this problem would to be to make Choice a string, then compare it to string values, or extract data from the string (for example with atoi) and assign it to other variables. C is a statically typed programming language, an int cannot become (or be compared to) a string because they are not of the same type. If you want arbitrary data from the user, the best way to approach that problem is probably to use a string. :-)
Read your input as array of chars
example
char bleh[250];
scanf ("%s", bleh);//or scanf ("%s", &bleh[0]);
and then use strcmp command to compare two arrays
strcmp(&bleh[0], "blabla"); //function will return 0 if two arrays match
hope this helps
"String" is const char *, you cannot compare using == in C++. You need to use strcmp to compare string.
strcmp returns zero if strings are same.
Few mistakes in the code.
use strcmp() to compare string.
Declare int Choice; to char Choice[50]
Remove & while reading string in scanf()
Comparing with if(Choice == 2817) is not correct. use if(strcmp(Choice , "2817") == 0)

C string - identical, and not matching? [duplicate]

This question already has answers here:
Using the equality operator == to compare two strings for equality in C [duplicate]
(9 answers)
Closed 9 years ago.
Got a small problem with C. Restricting myself to simple C (i.e. OS instructions), and two strings seem to not be the same. Here is my code:
char inputData[256];
int rid;
rid = read(0,inputData,256);
// Strip input
char command[rid];
int i;
for (i = 0; i<=rid-2; i++) {
command[i] = inputData[i];
}
command[rid-1] = '\0';
if (command == "exit") {
write(1,"exit",sizeof("exit"));
}
Now, if a user enters "exit" into the terminal when queried and hits enter, the if for detecting "exit" never gets run. Any ideas?
Thanks,
EDIT: I am commiting to git as I go, so the current version can be found at github.com/samheather/octo-os. It's very obviously not complete code, but it demonstrates the problem.
You can't compare strings with ==. You need to use strcmp.
if (strcmp(command, "exit") == 0) {
C strings are actually character arrays. You can think of "command" as a pointer to the first character. You want to compare every character in the string, not just the location of the first characters.
You should use strcmp to compare strings in C.
if(strcmp(command, "exit") == 0) //strcmp returns 0 if strings are equal
To quote:
A zero value indicates that both strings are equal. A value greater than zero indicates
that the first character that does not match has a greater value in str1 than in str2.
a value less than zero indicates the opposite.
As it stands right now, you're comparing the address of command with the address of the string literal "exit", which pretty much can't be the same.
You want to compare the contents, with either strcmp, or (if "only OS instructions" means no standard library functions) an equivalent you write yourself that walks through the strings and compares characters they contain.
As others said, == doesn't work with strings. The reason is that it would compare the pointers given.
In the expression
command == "exit"
command is a pointer to your array variable, while "exit" is a pointer to that string which resides in read-only data space. They can never be identical, so the comparison always is false.
That's why strcmp() is the way to go.
Use strcmp from the standard library.

Checking contents of char variable - C Programming

This might seem like a very simple question, but I am struggling with it. I have been writing iPhone apps with Objective C for a few months now, but decided to learn C Programming to give myself a better grounding.
In Objective-C if I had a UILabel called 'label1' which contained some text, and I wanted to run some instructions based on that text then it might be something like;
if (label1.text == #"Hello, World!")
{
NSLog(#"This statement is true");
}
else {
NSLog(#"Uh Oh, an error has occurred");
}
I have written a VERY simple C Program I have written which uses printf() to ask for some input then uses scanf() to accept some input from the user, so something like this;
int main()
{
char[3] decision;
Printf("Hi, welcome to the introduction program. Are you ready to answer some questions? (Answer yes or no)");
scanf("%s", &decision);
}
What I wanted to do is apply an if statement to say if the user entered yes then continue with more questions, else print out a line of text saying thanks.
After using the scanf() function I am capturing the users input and assigning it to the variable 'decision' so that should now equal yes or no. So I assumed I could do something like this;
if (decision == yes)
{
printf("Ok, let's continue with the questions");
}
else
{
printf("Ok, thank you for your time. Have a nice day.");
}
That brings up an error of "use of undeclared identifier yes". I have also tried;
if (decision == "yes")
Which brings up "result of comparison against a string literal is unspecified"
I have tried seeing if it works by counting the number of characters so have put;
if (decision > 3)
But get "Ordered comparison between pointer and integer 'Char and int'"
And I have also tried this to check the size of the variable, if it is greater than 2 characters it must be a yes;
if (sizeof (decision > 2))
I appreciate this is probably something simple or trivial I am overlooking but any help would be great, thanks.
Daniel Haviv's answer told you what you should do. I wanted to explain why the things you tried didn't work:
if (decision == yes)
There is no identifier 'yes', so this isn't legal.
if (decision == "yes")
Here, "yes" is a string literal which evaluates to a pointer to its first character. This compares 'decision' to a pointer for equivalence. If it were legal, it would be true if they both pointed to the same place, which is not what you want. In fact, if you do this:
if ("yes" == "yes")
The behavior is undefined. They will both point to the same place if the implementation collapses identical string literals to the same memory location, which it may or may not do. So that's definitely not what you want.
if (sizeof (decision > 2))
I assume you meant:
if( sizeof(decision) > 2 )
The 'sizeof' operator evaluates at compile time, not run time. And it's independent of what's stored. The sizeof decision is 3 because you defined it to hold three characters. So this doesn't test anything useful.
As mentioned in the other answer, C has the 'strcmp' operator to compare two strings. You could also write your own code to compare them character by character if you wanted to. C++ has much better ways to do this, including string classes.
Here's an example of how you might do that:
int StringCompare(const char *s1, const char *s2)
{ // returns 0 if the strings are equivalent, 1 if they're not
while( (*s1!=0) && (*s2!=0) )
{ // loop until either string runs out
if(*s1!=*s2) return 1; // check if they match
s1++; // skip to next character
s2++;
}
if( (*s1==0) && (*s2==0) ) // did both strings run out at the same length?
return 0;
return 1; // one is longer than the other
}
You should use strcmp:
if(strcmp(decision, "yes") == 0)
{
/* ... */
}
You should be especially careful with null-terminated string in C programming. It is not object. It is a pointer to a memory address. So you can't compare content of decision directly with a constant string "yes" which is at another address. Use strcmp() instead.
And be careful that "yes" is actually "yes\0" which will take 4 bytes and the "\0" is very important to strcmp() which will be recognized as the termination during the comparison loop.
Ok a few things:
decision needs to be an array of 4 chars in order to fit the string "yes" in it. That's because in C, the end of a string is indicated by the NUL char ('\0'). So your char array will look like: { 'y', 'e', 's', '\0' }.
Strings are compared using functions such as strcmp, which compare the contents of the string (char array), and not the location/pointer. A return value of 0 indicates that the two strings match.
With: scanf("%s", &decision);, you don't need to use the address-of operator, the label of an array is the address of the start of the array.
You use strlen to get the length of a string, which will just increment a counter until it reaches the NUL char, '\0'. You don't use sizeof to check the length of strings, it's a compile-time operation which will return the value 3 * sizeof(char) for a char[3].
scanf is unsafe to use with strings, you should alternatively use fgets(stdin...), or include a width specifier in the format string (such as "3%s") in order to prevent overflowing your buffer. Note that if you use fgets, take into account it'll store the newline char '\n' if it reads a whole line of text.
To compare you could use strcmp like this:
if(strcmp(decision, "yes") == 0) {
// decision is equal to 'yes'
}
Also you should change char decision[3] into char decision[4] so that the buffer has
room for a terminating null character.
char decision[4] = {0}; // initialize to 0
There's several issues here:
You haven't allocated enough storage for the answer:
char[3] decision;
C strings are bytes in the string followed by an ASCII NUL byte: 0x00, \0. You have only allocated enough space for ye\0 at this point. (Well, scanf(3) will give you yes\0 and place that NUL in unrelated memory. C can be cruel.) Amend that to include space for the terminating \0 and amend your scanf(3) call to prevent the buffer overflow:
char[4] decision;
/* ... */
scanf("%3s", decision);
(I've left off the &, because simply giving the name of the array is the same as giving the address of its first element. It doesn't matter, but I believe this is more idiomatic.)
C strings cannot be compared with ==. Use strcmp(3) or strncmp(3) or strcasecmp(3) or strncasecmp(3) to compare your strings:
if(strcasecmp(decision, "yes") == 0) {
/* yes */
}
C has lots of lib functions to handle this but it pays to know what you are declaring.
Declaring
char[3] decision;
is actually declaring a char array of length 3. So therefor attempting a comparison of
if(decision == "yes")
is comparing a literal against and array and therefor will not work. Since there is no defined string type in C you have to use pointers, but not directly, if you don't want to. In C strings are in fact arrays of char so you can declare them both ways eg:
char[3] decision ;
* char decision ;
Both will in point of fact work but you in the first instance the compiler will allocate the memory for you, but it will ONLY allocate 3 bytes. Now since strings in C are null terminated you need to actually allocate 4 bytes since you need room for "yes" and the null. Declaring it the second way simply declares a pointer to someplace in memory but you have no idea really where. You would then have to allocate memory to contain whatever you are going to put there since to do otherwise will more then likely cause a SEGFAULT.
To compare what you get from input you have two options, either use the strcomp() function or do it yourself by iterating through decision and comparing each individual byte against "Y" and "E" and "S" until you hit null aka \0.
There are variations on strcomp() to deal with uppercase and lowercase and they are part of the standard string.h library.

Resources