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
Related
I've recently faced a programming problem, and it seems to me that the most optimized way of solving it is by using goto, even though it's not a good practice. The problem is: tell the user to enter a positive natural number ( > 0) and read the input. If this number is valid, tell the user the square of that number. Do this while the input is correct. I came up with a few solutions, but all of them seem to have problems. Here are two of them:
Solution 1 - Problem: Uses goto
#include <stdio.h>
int main()
{
int num;
_LOOP:
printf("Enter a positive natural number: ");
scanf("%i", &num);
if (num > 0) {
printf("Square: %i\n", num * num);
goto _LOOP;
}
printf("Invalid number\n");
return 0;
}
Solution 2 - Problem: Double-checks if num > 0 (code repetition)
#include <stdio.h>
int main()
{
int num;
do {
printf("Enter a positive natural number: ");
scanf("%i", &num);
if (num > 0)
printf("Square: %i\n", num * num);
} while (num > 0);
printf("Invalid number\n");
return 0;
}
Obviously, there are more ways to solve the problem, but all the other ones I came up with that do not use goto encouter the same code repetition problem. So, is there a solution where both goto and code repetitions are avoided? If not, which one should I go for?
Here's half the answer; try to fill in what's missing. Remember that sometimes it's better to structure your loop as "do something until..." rather than "do something while..."
for (;;) {
printf("Enter a positive natural number: ");
scanf("%i", &num);
if (num <= 0)
break;
printf("Square: %i\n", num * num);
}
printf("Invalid number\n");
[updated with #rdbo's answer]
What about breaking out of the loop? This is basically a goto statement to the end of the loop without explicitly using goto.
#include <stdio.h>
int main()
{
int num;
while(1) {
printf("Enter a positive natural number: ");
scanf("%i", &num);
if (num > 0) {
printf("Square: %i\n", num * num);
} else {
printf("Invalid number\n");
break;
}
}
return 0;
}
The other option: check a bool that stores if the continue condition is met. It reads much easier than the infinite loop/break approaches (to me) and there's no code repetition.
#include <stdio.h>
#include <stdbool.h>
int main()
{
int num;
bool bContinue;
do {
printf("Enter a positive natural number: ");
scanf("%i", &num);
if (num > 0){
printf("Square: %i\n", num * num);
bContinue = true;
}
else{
printf("Invalid number\n");
bContinue = false;
}
} while (bContinue);
return 0;
}
For starters if you expect a non-negative number then the variable num should have an unsigned integer type for example unsigned int.
As it is written in your question the user can enter an invalid data or interrupt the input. You have to process such a situation.
Also the multiplication num * num can result in an overflow.
And using goto instead of a loop is indeed a bad idea.
Pay attention to that you should declare variables in minimum scopes where they are used.
To use the for loop for such a task is also a bad idea. It is much expressive to use a while loop.
The program can look the following way
#include <stdio.h>
#include <stdbool.h>
int main(void)
{
while ( true )
{
printf( "Enter a positive natural number: " );
unsigned int num;
if ( scanf( "%u", &num ) != 1 || num == 0 ) break;
printf( "Square: %llu\n", ( unsigned long long )num * num );
}
puts( "Invalid number" );
return 0;
}
The program output might look like
Enter a positive natural number: 100000000
Square: 10000000000000000
Enter a positive natural number: 0
Invalid number
Or it would be even better to move the last output statement inside the while statement. Fo rexample
#include <stdio.h>
#include <stdbool.h>
int main(void)
{
while ( true )
{
printf( "Enter a positive natural number: " );
unsigned int num;
if ( scanf( "%u", &num ) != 1 || num == 0 )
{
puts( "Invalid number" );
break;
}
printf( "Square: %llu\n", ( unsigned long long )num * num );
}
return 0;
}
I am a bit surprised nobody suggested functional decomposition yet.
Instead of writing a big pile of primitive statements, cut main up into smaller functions.
Apart from readability/maintainability benefits, it also helps eliminate code duplication in a very natural way.
In OP's case, getting input from the end user is a separate responsibility, and makes a good choice for a separate function.
static bool user_enters_number(int *ptr_to_num)
{
printf("Enter a positive natural number: ");
return scanf("%i", ptr_to_num) == 1;
}
Notice user_enters_number explicitly tests the return value of scanf.
This improve end-of-file handling.
Likewise, you could give number validation its own function.
This may seem like overkill (it's just num > 0, right?), but it gives us the opportunity to combine the validation with the resulting error message.
Printing "Invalid number" at the end of main feels wrong. Invalid numbers are not the only exit condition; end-of-file is another.
So instead, I will let the validation function determine the message.
As a bonus, this makes it possible to support multiple error types (e.g. separate messages for negative numbers and for zero).
static bool is_valid_number(int num)
{
bool ok = (num > 0);
if (!ok) printf("Invalid number\n");
return ok;
}
We now have two boolean-typed functions that can be neatly chained together with && and put inside the condition part of a loop, which is an idiomatic way of saying: if either one of these functions fails (i.e. returns false), immediately exit the loop.
What's left, is a very clean main function.
int main(void)
{
int num;
while (user_enters_number(&num) && is_valid_number(num))
{
printf("Square: %i\n", num * num);
}
}
To appreciate the benefits in terms of maintainability, try rewriting this code so that it accepts two numbers and prints their product.
int main(void)
{
int num1, num2;
while (user_enters_number(&num1) && is_valid_number(num1) &&
user_enters_number(&num2) && is_valid_number(num2))
{
printf("Product: %i\n", num1 * num2);
}
}
The changes are trivial, and limited to a single function
(though you might consider adding a parameter input_prompt to user_enters_number).
There is no performance penalty for this 'divide-and-conquer' approach: a smart compiler will do whatever is necessary to optimize the code, e.g. inline the functions.
I've been trying to write a recursive function that scans a series of numbers and returns the sum of the numbers in odd indexes minus the sum of numbers in even indexes.
biggest problems: the function is not supposed to receive any parameters when called upon; and I have to do it in one function.
Edit: so, I wrote this code and it seems to work for the most part, but the problem is I wasn't supposed to send any parameters with the function (f wasn't supposed to exist)
void Ex1() // this is sort of like the main
{
int f = 1, res;
res = sumofodd_even(f);
printf("sum is: %d\n", res-1);
}
int sumofodd_even(int flag)
{
int num = 0;
printf("enter a number. to stop enter -1 >> \n");
scanf_s("%d", &num);
if (num != -1)
{
if (flag == -1)
num *= -1;
return num + sumofodd_even((-1) * flag);
}
}
btw: can't use pointers or arrays...
will appreciate any help.
One approach might be to just use a boolean flag that gets flipped at every recursion:
#include <stdbool.h>
#include <stdio.h>
int sumofodd_even(const bool odd) {
printf("enter a number. to stop enter -1 >> ");
int num = 0;
scanf("%d", &num);
if (num == -1) {
return 0; // breaks the recursion
}
num *= odd ? 1 : -1;
return num + sumofodd_even(!odd);
}
int main(void) {
printf("sum is: %d\n", sumofodd_even(false)); // zero is even, thus we start with odd == false
return 0;
}
you can use odd to mark if the read value should be treated as an odd number or as an even number, and thus change its sign accordingly.
Alternative to counting iterations or flipping a flag is to simply use two functions. After all, your algorithm has two states: process an even-indexed number, or process an odd-indexed number. Rather than have one function with an if statement, just use a function for each state, and have those functions transition between states by calling on each other.
int sum_of_odd() {
// <Ask user for input>
if (num == -1) {
return 0;
}
return sum_of_even() + num;
}
int sum_of_even() {
// <Ask user for input>
if (num == -1) {
return 0;
}
return sum_of_odd() - num;
}
And of course you'd start the algorithm by calling sum_of_odd(), since the first number is odd-indexed (unless you want to "index by zero").
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);
So here is my code. Its a school assignment. I had to make a program to calculate the square root of a number using a method the Babylonians developed etc, that's not the important part. What I was wondering is if it's possible to ignore letters in my scanf so that when I input a letter it doesn't go berserk in my terminal. Any help is welcome and greatly appreciated.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
double root_Approach(double s); // defines the two functions
void ask_Number(void);
int main() {
ask_Number(); // calls function ask_Number
printf("\n\n");
system("pause");
return 0;
}
double root_Approach(double s) {
double approach;
approach = s;
printf("%.2lf\n", s); // prints initial value of the number
while (approach != sqrt(s)) { // keeps doing iteration of this algorithm until the root is deterimened
approach = (approach + (s / approach)) * 0.5;
printf("%lf\n", approach);
}
printf("The squareroot of %.2lf is %.2lf\n",s, sqrt(s)); // prints the root using the sqrt command, for double checking purposes
return approach;
}
void ask_Number(void) {
double number;
while (1) {
printf("Input a number greater than or equal to 0: "); // asks for a number
scanf_s("%lf", &number); // scans a number
if (number < 0) {
printf("That number was less than 0!!!!!!\n");
}
else {
break;
}
}
root_Approach(number);
}
Scanf reads whatever may be the input from the terminal (character or integer)
One way you can do is to check the return statement of scanf whether the read input is integer or not an integer.
Here is the sample code
int num;
char term;
if(scanf("%d%c", &num, &term) != 2 || term != '\n')
printf("failure\n");
else
printf("valid integer followed by enter key\n");
`
this link may be helpful
Check if a value from scanf is a number?
I've been at this project for hours and hours trying to figure this out but I'm to the point of brain dead where everything I read leaves me confused.
The idea is to enter a number and the program will tell me whether it is right or wrong. Every single time, the end response after I enter a number is that the number is too low.
Also, the final answer states that the answer is too low and that it's correct at the same time.
Finally, this thing is suppose to ask again if the number entered is incorrect, yet I have no knowledge of how to do this.
Literally, the tiniest advice is much appreciated at this point. It's been a long, groaning night.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int number;
//new function
void welcomeMessage(){
printf("Welcome to my new guessing game!\n");
printf("Let's get started!\n");
}
//new function
int randomNumber(){
int range;
srand(time(NULL));
range = (20 - 1) + 1;
number = rand() % range + 1;
return 0;
}
//new function
int guessInput(){
int guess, range;
printf("I'm thinking of a number between 1 and 20\n");
printf("Care to give it a guess? Be careful! You only get 4 tries!\n");
scanf("%d", &guess);
return 0;
}
//new function
int wrongAnswer(){
int guess, number;
if(guess < number)
{
printf("Try again, your guess is too low\n");
return 0;
}
else if(guess > number)
{
printf("Give it another try, your guess was a bit to high\n");
return 0;
}
return 0;
}
//new function
int correctAnswer(){
int guess, number;
if(guess == number)
printf("Great job! That time you got it right!\n");
return 0;
}
int main(){
welcomeMessage();
randomNumber();
guessInput();
wrongAnswer();
correctAnswer();
}
You're not actually passing the value of guess to wrongAnswer() or correctAnswer(). guess in those two functions is uninitialized and doesn't contain the value stored in guessInput(). This is why wrongAnswer tells you that the guess is too low and correctAnswer tells you that it's correct.
You'll also want to remove the number declaration within those functions. You have a global number right now that stores the random number, but the new number variable declared within your functions will take precedence -- it's uninitialized and doesn't contain the random number like you think it does.
You may want to adjust your wrongAnswer() and correctAnswer() functions to take guess as an integer argument, and remove the guess and number declarations within those two functions. Something like
int wrongAnswer(int guess);
int correctAnswer(int guess);
You may also want to consider having your guessInput() function return the value of guess. Try something like
int guessInput()
{
int guess;
printf("I'm thinking of a number between 1 and 20\n");
printf("Care to give it a guess? Be careful! You only get 4 tries!\n");
scanf("%d", &guess);
return guess;
}
int main()
{
...
int guess = guessInput();
wrongAnswer(guess);
correctAnswer(guess);
...
}
This way you're passing the value of guess to your two functions so that they can actually evaluate whether the number is correct or incorrect.
You'll also want to look at the value of your return functions. Right now they aren't really telling you anything, and they return 0 regardless. Consider changing them to return 0 if the guess was correct and return 1 if the guess was incorrect.
int correctAnswer(int guess)
{
if(guess == number) {
printf("Great job! That time you got it right!\n");
return 0;
} else {
return 1;
}
}
With this information you can create a while loop to continually ask the user for input until they input the correct answer. Something like
int main()
{
...
int is_correct = 1, is_wrong = 1;
int guess;
while (is_correct == 1) {
guess = guess_input();
is_wrong = wrongAnswer(guess);
is_correct = correctAnswer(guess);
}
...
}
The while loop above will call each of the three functions, forever, until the user guesses the correct input. It evaluates is_correct == 1, constantly checking the value of is_correct, and repeating itself. When is_correct == 0 the loop will break and your program will terminate. This is where the return values I mentioned above come in -- a return value of 0 indicates a correct answer and will allow your program to stop. A return value of 1 will repeat the loop. There are other ways to do this, but it may help while you're starting out.
Hopefully this helps you out. I'd also consider redesigning your wrongAnswer() and correctAnswer() functions -- do you really need two? Could you reduce that to one function?
The Most basic issue that i see with the program is that you are not passing values to the functions. Each function is just working in itself and the value or should i say the 'number' it has to work with is not being passed into them.
You can use global variables or pass the values directly. This is what i would do:
The input function:
int guessInput(){
int guess, range;
printf("I'm thinking of a number between 1 and 20\n");
printf("Care to give it a guess? Be careful! You only get 4 tries!\n");
scanf("%d", &guess);
return guess;}
The Random Number Generator Function:
int randomNumber(){
int range;
srand(time(NULL));
range = (20 - 1) + 1;
number = rand() % range + 1;
return number;}
The Answer Function: ( you really don't need 2 functions for this )
int Answer(int guess, int number){
int counter=0;
if(guess < number)
{
printf("Try again, your guess is too low\n");
counter=1;
}
else if(guess > number)
{
printf("Give it another try, your guess was a bit to high\n");
counter=1;
}
else if(guess == number)
{
printf("Great job! That time you got it right!\n");
counter=2;
}
return counter;}
Now that all your functions can accept variables, Modify the Main function
int main(){
int number=0;
int guess=0;
int answr=0; // This does not have to exist but since your doing a return.
welcomeMessage();
number=randomNumber();
guess=guessInput();
Do {
answr=Answer(guess,number);
}(while answr<2)
}
So when the counter reaches 2, which means that the answer is right, the while loop will stop when the correct answer is guessed by the user.
PS: You may need to polish my code a bit since im also in a brain dead mode atm. :D