(C programming) while loop only works in a specific order - c

I'm writing a silly code as a joke, sort of a number guessing thing. I thought it was fine until I realized the correct things would only print if I put in the numbers in a specific order. I'm a bit of a beginner, so I'm not sure why it's only printing correctly if I type in the numbers in an order. Is this a condition of while loops in general? Is there a way I can fix this so that it doesn't matter what order the numbers go in? Any insight would be greatly appreciated.
Here is my code:
#include <stdio.h>
#include <math.h>
#include <unistd.h>
#include <string.h>
int number;
int main()
{
printf("Enter a number!\n");
scanf("%d", &number);
while ((number != 69) && (number != 420))
{
printf("hmmm, not the number i was looking for... Enter another number!\n");
scanf("%d", &number);
while (number == 666)
{
printf("what are you, emo? try again!\n");
scanf("%d", &number);
while (number == 420)
{
printf("lol close, try the other Funny Number\n");
scanf("%d", &number);
while ((number != 69) && (number != 420))
{
printf("hmmm, not the number i was looking for... Enter another number!\n");
scanf("%d", &number);
}
while (number == 69)
{
printf("haha nice\n");
return 0;
}
}
}
}
}

What you may be running into is you enter a number and then it gets stuck in an "inner" loop scanning and checking and failing an inner condition instead of all of them.
I'm not sure if you have yet to discover if/else if/else but this is normally how you might check conditional statements. I will write this in pseudo code to give you a chance to write it yourself in C.
number = 0
print "Enter a number"
while number != 69
number = get number
if number == 666
print "What are you..."
else if number == 420
print "lol close..."
else if number == 69
print "haha nice..."
else
print "hmmm..."
For extra fun check out switch statements.

Related

Guessing Game in C programming

I built a guessing game in C programming using while loop, and I am having a problem with it during execution. So, when I print a number less than the guess number or greater than the guess number, I get the correct answer. But when the user enters the right answer, the screen shows the statement for the greater number "The number you entered is greater than the Secret Number." and then it shows the right statement below this "This is the secret Number." I think the problem could be because else statement does not define the condition for greater number but I am not sure how to solve this. Can somebody help me?
#include <stdio.h>
#include <stdlib.h>
int main()
{
//Guessing game
const int SecretNum = 4;
int guess;
while (guess != SecretNum){
printf("Enter a number: ");
scanf("%d", &guess);
if (guess < SecretNum){
printf("The number you entered is less than the Secret Number. \n");
} else printf("The number you entered is greater than the Secret Number.\n");
}
printf("This is the secret number.\n");
return 0;
}
You think the problem could be because else statement does not define the condition for greater number, so you should add that.
Also you have to initialize guess before using its value.
Formatting your code using indent properly is another important portion.
#include <stdio.h>
#include <stdlib.h>
int main()
{
//Guessing game
const int SecretNum = 4;
int guess = !SecretNum; /* initialize guess : guess will be different value from SecretNum using this */
while (guess != SecretNum){
printf("Enter a number: ");
scanf("%d", &guess);
if (guess < SecretNum){
printf("The number you entered is less than the Secret Number. \n");
} else if (guess > SecretNum) /* add condition */
printf("The number you entered is greater than the Secret Number.\n");
}
printf("This is the secret number.\n");
return 0;
}

My for loop sequence is not ending with the perimeters are met to end

For the below code I created a RNG and ask the user to input a number from one to 20 until they guess the correct number. When they guess the correct number the printf prints the correct text so I know guesses[i] == randomNumber
I would think that the for loop would terminate since now guesses[i] != randomNumber no longer holds a true value. The loop is not terminating and continues to ask the user to guess.
Am I missing something here?
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <ctype.h>
#include <stdlib.h>
int main(void) {
time_t t;
srand(time(&t));
int randomNumber = (rand() % 19) + 1;
int guesses[30] = {0};
int i;
for (i = 0; guesses[i] != randomNumber; i++)
{
printf("Hello master, I will grant you 3 wishes if you can guess what number I have selected between 1 and 20: ");
scanf("%d", &guesses[i]);
if (guesses[i] == randomNumber) {
printf("It took you %d guesses to guess correct but I lied I cannot grant you any wishes, have a nice day. \n\n", i + 1);
}
else if(guesses[i] < randomNumber) {
printf("You guessed too low, try a higher number. \n\n");
}
else if(guesses[i] > randomNumber) {
printf("You guessed too high, try a lower number. \n\n");
}
}
return 0;
}
When the user inputs its guess, i increases by the loop increment instruction, and now your condition is applied to guess[i] which is actually the next i not the input user.
Welcome to SO..
I believe that testing the condition (guesses[i] != randomNumber) happens before advancing i (i++), so you are actually testing against i that was already advanced by 1
You can either try to use ++i instead of i++
OR
You can use a while loop instead of a for loop:
i = 0;
while (guesses[i] != randomNumber && i < 30) {
i++;
printf("Hello master, I will grant you 3 wishes if you can guess what number I have selected between 1 and 20: ");
scanf("%d", &guesses[i]);
if (guesses[i] == randomNumber) {
printf("It took you %d guesses to guess correct but I lied I cannot grant you any wishes, have a nice day. \n\n", i + 1);
}
else if(guesses[i] < randomNumber) {
printf("You guessed too low, try a higher number. \n\n");
}
else if(guesses[i] > randomNumber) {
printf("You guessed too high, try a lower number. \n\n");
}
}
Note how I also added a test for i < 30 to not get out of the array index bounds

If statement inside while loop with the same condition

Is there a better way to write the following code by eliminating the repeated condition in the if statement in C?
while (n < 0) {
printf("Enter a positive integer: ");
scanf("%d", &n);
if (n < 0) {
printf("Error: please enter a positive integer\n");
}
}
Thank you.
Simply rework your loop breaking when correct input is given. This way the check is done only one time:
while (1)
{
printf("Enter a positive integer: ");
scanf("%d", &n);
if (n >= 0)
break;
printf("Error: please enter a positive integer\n");
}
And, as specified in comments, an optimized compiler should be able to reverse the loop by itself.
This is something that IMO is best accomplished with a bit of refactoring:
#include <stdio.h>
#include <stdbool.h>
static bool get_postive_integer(int *pOut) {
int n;
printf("Enter a positive integer: ");
scanf("%d", &n);
if(n < 0)
return false;
*pOut = n;
return true;
}
int main(void)
{
int n;
while (!get_postive_integer(&n)) {
printf("Error: please enter a positive integer\n");
}
}
Give the operation a name, check that it fails, and only then print a message accordingly. The success or failure condition is only coded once here, in the named operation.
You could use:
while (printf("Enter a positive integer: ") > 0 &&
scanf("%d", &n) == 1 &&
n < 0)
{
printf("Error: please enter a positive integer\n");
}
This stops if the printf() fails, if the scanf() fails, or if the value in n is non-negative. It's a good idea to always check that the scanf() succeeds. It is merely convenient that printf() returns the number of characters it wrote (or a negative number on failure) so it can be used in a condition too. You could add fflush(stdout) == 0 && into the stack of operations too.
Or you could decide that the code in the condition should be in a function:
static int read_positive_integer(void)
{
int value;
if (printf("Enter a positive integer: ") > 0 &&
fflush(stdout) == 0 &&
scanf("%d", &value) == 1 &&
value >= 0)
return value;
return -1;
}
and then the calling code is:
while ((n = read_positive_integer()) < 0)
printf("Error: please enter a positive integer\n");
There are many variations on the theme; you might wrap the while loop into a function; you might make the prompts into parameters to the function. You might decide to be more careful about reporting what goes wrong (different actions if printf() fails compared with what happens if scanf() returns 0 (non-numeric data in the input) or EOF (no more data in the input).
The following examples are presented in the spirit that people should know what is available in the language.1 The way I would usually write the code is shown in Frankie_C’s answer. As some have noted, optimization usually makes this simple case not worth worrying about, but the question is not limited to a simple evaluation like n < 0; the test might be a function call to some expensive evaluation of more complicated criteria.
Folks are not going to like this, but:
goto middle;
do
{
printf("Error, please enter a positive integer\n");
middle:
printf("Enter a positive integer: ");
scanf("%d", &n);
} while (n < 0);
If you are vehemently opposed to goto, you can use a stripped-down version of Duff’s device:
switch (0)
do
{
printf("Error, please enter a positive integer\n");
case 0:
printf("Enter a positive integer: ");
scanf("%d", &n);
} while (n < 0);
But you should not.
Footnote
1 Commonly, software engineers will have to work with code written by others, so they must be prepared to recognize and understand anything expressible in the language, even if that is just a first step toward rewriting it into better code. And occasionally situations arise where “ugly” code becomes desirable for commercial or other practical reasons.
Another alternative is to split into a function:
int func(){
int n;
printf("Enter a positive integer: ");
scanf("%d", &n);
return scanf("%d", &n) == 1 ? n : -1;
}
and the loop becomes
while ((n = func()) < 0){
printf("Error: please enter a positive integer\n");
}
although the assignment in the condition check is not to everyone's taste. Note that I return -1 if the return value of scanf is not 1, something that you should always check.
What I do though in this situation (See Eric's answer) is to write
switch (0) do {
printf("Error, please enter a positive integer\n");
case 0:
printf("Enter a positive integer: ");
scanf("%d", &n);
} while (n/*ToDo - make sure n is initialised if scanf fails*/ < 0);

Algorithm that asks for numbers until zero is input

I'm trying to make an algorithm in C that asks you to input any number, and stops asking when you input the number 0. I'm supposed to do it with a while loop, but it doesn't work and I tried everything I've learned. This is my code that doesn't work:
#include<stdio.h>
int main()
{
int number;
while(number != 0)
{
printf("Introduce a number: ");
scanf("%i",&number);
}
return 0;
}
Hopefully it's not too late to bring my two cents to the party.
The solution which others suggest is definitely possible and working solution, however, I think it can be done in a slightly neater way. For cases like this, do while statement exists:
#include <stdio.h>
int main() {
int number; // Doesn't need to be initialized in this case
do {
printf("Introduce a number: ");
if (scanf("%i", &number) != 1) { // If the value couldn't be read, end the loop
number = 0;
}
} while (number != 0);
return 0;
}
The reason I think this solution is better is just that it doesn't bring any other magic constants to the code, hence it should be better readable.
If someone saw int number = 42;, for example, he'd be asking - Why 42? Why is the initial value 42? Is this value used somewhere? The answer is: No, it is not, thus it's not necessary to have it there.
You need to assign a number to number before using it in the condition.
You have two options: a) use a dummy initial value, or b) scanf before test
// a) dummy value
int number = 42;
while (number != 0) { /* ... */ }
or
// b) scanf before test
int number; // uninitialized
do {
if(scanf("%i", &number) != 1) exit(EXIT_FAILURE);
} while (number != 0);
int number = 1;
while(number != 0){
printf("Introduce a number: ");
scanf("%i",&number);
}
Scanf will pause loop and waiting for typing a number

Number guessing game in C

I had a problem at doing my number guessing game in C. While running the program it shows up return function when I put the char element in there. Can someone help me with this? Also how can I improve my code in order to make it workable? I'M really stuck with this issue.
Here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>
int main()
{
char s, n, q;
int b;
bool (1=true), (0=false);
int secret;
secret = rand();
int guess;
int seed;
srand(seed);
printf("Welcome to the guessing game!\n");
do{
printf("Menu: (s) to start a new game, (n) to set a new range, or (q) to quit:\n");
scanf("%s, %s, %s", s, n, q);
if((s==1))
{
printf("The secret number is Between 0 AND rand(). Guess\n");
scanf("%s", b);
}
else if((n ==1))
{
printf("Enter a new MAXIMUM\n");
scanf("%s", rand());
if(( s ==1))
{
printf("The secret number is Between 0 AND rand(). Guess\n");
scanf("%s", b);
printf("The secret number is between 0 and rand() Guess:");
scanf("%s", b);
if(guess = rand()){
printf("Congratulations you won, You took %d guesses!", b);
break;
}
else if(guess > rand())
{
printf("Too High, Guess again:");
}
else if(guess < rand()){
printf("Too Low, Guess Again:");
}
else{
printf("This number out of the number set!");
}
}
}
else{
printf("Unrecognized command");
}
}while(q == 1);
printf("You quited the game");
return 0;
}
This code has myriad issues to resolve. I'd suggest approaching your code writing process in small steps. It appears as though you wrote the entire program in one burst, ran it, and found it didn't work instead of incrementally adding small features and running each one to verify it works before moving on to the next step. Not doing this results in a difficult to debug program and a lack of understanding about how the program operates.
To be specific, try writing a three or four line program that collects and prints user input. Is the output working as you expect? Did you test its robustness on a variety of input? Can you write it to use a variety of data types? If something isn't working, did you research the problem and resolve it before steaming ahead?
Some areas of your program to investigate:
bool (1=true), (0=false); doesn't compile and isn't necessary for the program. If you #include <stdbool.h> you don't need to do this (you can simply write if (something == true)).
srand() is not properly called or seeded. Seed it once per program using the time() call from the header you included and call rand() once per game. Use the % operator to set the function output between 0 and max.
On each turn, compare guess against the value you previously stored rand() in rather than calling rand() during each comparison, which makes the game logic arbitrary.
%s input isn't appropriate; read chars %c and ints %d, passing appropriate variable references to scanf. scanf("%s, %s, %s", s, n, q); collects 3 whitespace separated strings for input instead of 1 char as the prompt suggests.
There is no game loop. Add an inner loop to run a game when the user chooses s and move your guess/response logic there.
Use more verbose variable names and correct brackets and indentation to improve readability.
Putting it all together, here's one possible working version. It could make better use of functions and implement secure user input (exercises for the reader):
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
char menu_choice;
int guess;
int guesses;
int secret;
int max = 100;
srand(time(NULL));
printf("Welcome to the guessing game!\n");
for (;;) {
printf("\nMenu: (s) to start a new game, (n) to set a new range, or (q) to quit: ");
scanf(" %c", &menu_choice);
if (menu_choice == 's') {
guesses = 0;
secret = rand() % max;
for (;;) {
printf("\nThe secret number is between 0 and %d. Enter a guess: ", max);
scanf("%d", &guess);
guesses++;
if (guess == secret) {
printf("\nCongratulations, you won! You guessed %d in %d guesses!\n", secret, guesses);
break;
}
else if (guess > secret) {
printf("Too high! Guess again.");
}
else if (guess < secret) {
printf("Too low! Guess again.");
}
else if (guess >= max) {
puts("Out of range");
}
}
}
else if (menu_choice == 'n') {
printf("\nEnter a new maximum: ");
scanf("%d", &max);
}
else if (menu_choice == 'q') {
puts("\nGoodbye!");
break;
}
else {
puts("\nUnrecognized command.");
}
}
return 0;
}
Sample run:
Welcome to the guessing game!
Menu: (s) to start a new game, (n) to set a new range, or (q) to quit: n
Enter a new maximum: 50
Menu: (s) to start a new game, (n) to set a new range, or (q) to quit: s
The secret number is between 0 and 50. Enter a guess: 25
Too low! Guess again.
The secret number is between 0 and 50. Enter a guess: 37
Too low! Guess again.
The secret number is between 0 and 50. Enter a guess: 43
Too low! Guess again.
The secret number is between 0 and 50. Enter a guess: 47
Congratulations, you won! You guessed 47 in 4 guesses!
Menu: (s) to start a new game, (n) to set a new range, or (q) to quit: q
Goodbye!
printf("Menu: (s) to start a new game, (n) to set a new range, or (q) to quit:\n");
scanf("%s, %s, %s", s, n, q);
you dont need to use three variables s,n,q. you should ask the user to enter a single choice. either to start a new game or to quit or aything else.
secondly, rand() returns a random number every time. you are supposed to store random number somewhere. like this
rand_num=rand()
also
if(guess = rand())
is a wrong way of comparison. this should be
if(guess==rand_num)
finally binary search is the solution for your problem. please refer it on internet

Resources