Wondering about while loop - c

I started learning C 3 weeks ago, and while learning while loops I tried to build an addition program, basically you keep adding numbers it additions them and after 2nd number it gives you a subtotal for every addition, and if you press 0 to quit It gives you a final sum then quits.
Now I have one main, one additional question. The main question is, I had to use sum = 0 before the while functions, if I use it after "the while" it gives me the number I entered as the result. Now I really wonder what is the idea behind it. When I write it like below does it equates "sum with 0"
for the start and changes the value as I enter another number, or there is some other idea behind it.
And the additional question is , why do I need to use 2 getchar(); to make my program stay on the screen, why not one?
#include <stdio.h>
int main(void)
{
float num;
float sum;
printf(" please enter a number +0 to start the program (0 to quit): \n");
scanf(" %f", &num);
sum =0; //THIS HERE**********************
while (num > 0)
{
printf("please enter integer:\n");
scanf("%f", &num);
sum = sum + num;
printf("current sum is = %f\n", sum);
}
printf("final sum is = %f\n", sum);
getchar();
getchar();
return 0;
}

If you put sum=0 inside the while loop it will be called each time the while loop loops.
This means when you reach sum=sum+num, you will actually be calculating sum=0+num.
You have two use two getchar() calls because the first one is sucking up an additional character that was not absorbed by your scanf. Probably this character is a newline, so you cannot see it. The second getchar() then keeps your terminal open because it is waiting for a character.
To figure out if my hypothesis is correct about the first getchar() you could try this:
char temp = getchar();
printf("%d",(int)temp); //Print out the character number from the first getchar
getchar(); //This keeps the window open

If I use it after the while it gives me the number I entered as the result.
This is because when you do this
while (num > 0) {
sum = 0;
...
sum = sum + num;
}
the value that has been accumulated by sum on prior iterations of the while loop gets erased each time the loop iterates, meaning that only the last value would be added to sum (and kept as the result of the additions).
why do I need to use 2 getchar();
Because when scanf consumes the last number the end-user has entered, it reads everything up to, but not including, the '\n' character, which corresponds to the Enter key. This '\n' character remains in the buffer, waiting to be consumed by your program. The first call of getchar() consumes that "lingering" '\n', while the second one makes your program stay on screen until you press enter again.

= in most programming languages is different from the mathematical =. It does not mean that the two sides will permanently be equal to each other; rather, it means that the right-hand side should be computed and that the result should be assigned to the variable on the left-hand side. Later, another line might change the variable value to something else.
Thus, sum = sum + num; means that the current values of sum and and num are to be added, and the result is to be put back into sum. In order for this to work the way you wish, sum must be 0 the first time this line is executed; hence, you need sum = 0; somewhere. However, if this line is inside the loop, it is repeatedly executed, so that the result of the previous summation disappears and is replaced with 0 before each new number.

Related

Are there better ways to clear stdin when looking for a specific kind of input in C?

fairly new programmer here just trying to understand if there is a better way to do this and hoping to get some feedback.
TL;DR: Is there a better way to clear stdin when looking for a specific input?
For some background, I've been learning C for the past 3 weeks and scanf() has been our "go to" function for user input. After looking around for answers to this question, I'm beginning to learn that scanf() is not always preferred.
In this part of the assignment that I'm working on, I created this while loop that is supposed to run while the user input is a nonzero, positive integer. It took a while, but to get to this point I now understand that if a string is inputted instead of an integer when scanf("%d", &variable); is assigned while using leads to an infinite loop as stdin does not get cleared.
I tried to solve this problem by checking to see the return of the scanf() functions, and running the loop while the return is equal or less than 0 (which would mean that the scanf() function broke and did not return anything since it saw a char instead of an int).
The thing is, the code seems to work great until we encounter one scenario, which is where we have characters followed by an integer.
For example:
Input = 1
program runs with no issues
Input = string
program runs loop, asks for new valid input
Input = string string
program runs loop, asks for new valid input
Input = 123string
program proceeds, but then next loop with an int scanf() is infinite. 123 is stored as an int to variable.
My current understanding of the issue is that scanf() reads the integers until we get to the characters and then "string\n" gets stored to stdin, creating an infinite loop in the next part. To solve the issue, I added a fflush(stdin); before the next integer scanf() loop which seems to work.
So my question is: Would somebody be willing to show me some other ways to do this other than adding a fflush(stdin); line before every int scanf() loop? I'm sure there are better ways but I don't rightly know who to ask and the internet seemed like a good resource. Thank you.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int squareLen = 0;
int numColors = 0;
int infiniteLoopStop;
// Asks for user input of desired Square Length
printf("Please enter the finished side length (in inches) of one square.\n> ");
while (squareLen < 1) {
infiniteLoopStop = scanf("%d", &squareLen);
if (infiniteLoopStop <= 0 || squareLen < 1) {
printf("\nInvalid input. Enter a nonzero, positive integer.\n> ");
fflush(stdin);
}
}
// Temporary solution to problem
fflush(stdin);
// Asks for int input of colors and loops while number of colors is not 2 or 3
printf("How many colors are you using? Enter 2 or 3.\n> ");
while (numColors < 2 || numColors > 3) {
infiniteLoopStop = scanf("%d", &numColors);
if (infiniteLoopStop <= 0 || numColors < 2 || numColors > 3) {
printf("Invalid, please enter 2 or 3.\n> ");
fflush(stdin);
}
}
printf("\n");
return 0;
}

Why does my program return the first inputted value without the decimal every run?

#include <stdio.h>
int main (void) {
int count, value;
double avg, sum;
count = 0;
sum = 0;
printf("please input how many integers you have \n");
scanf("%d", &count);
for (int i = 0; i < count; i++) {
printf("please input your values \n");
scanf("%d", &value);
sum = sum + value;
}
avg = sum / count;
printf("your average is " "%f", avg);
}
Example: count input is 4. input values is 7.6, 1, 2, 3.
I understand that in the for loop scanf sees 7.6 first, but disregards the decimal point as it is not a valid form of input, and passes it along every subsequent scanf in the loop though they never truly accept an input. This results in the only inputted value as 7, but then the program should continue to divide 7 by 4 to retrieve the "Expected" average, but that is not the case. I end up with 7.000000, which I can't figure out why is happening.
Disregard the fact that I am prompting the user to input integer values even though floating point values were inputted because it is part of my homework assignment. Any hints or references to what I should study would be great
I understand that in the for loop scanf sees 7.6 first, but disregards the decimal point [..]
No. That's a matching failure as the input you enter (7.6) doesn't match the format specifier %d. Hence, scanf() fails. That's why you should always check the return code of all the standard functions. See 7.21.6.2 The fscanf function.
If you want to be able to read floating point values then you should read (change your code) to read floats (or doubles).
For example to read a double:
double value;
if (scanf("%lfd", &value) != 1) {
/* handle failure */
}
A general suggestion: Don't use scanf() if at all possible. Please read Why does everyone say not to use scanf? What should I use instead? for further explanation.
Your reasoning seems to be correct, except for the assumption that scanf will set value to zero on the subsequent iterations. Instead, after reading up to the period on the first iteration and assigning 7 to value, on subsequent iterations scanf will see the period, conclude that the input doesn't match the format, and not touch value at all, leaving it as 7 on every iteration. (It should return 1 on the first iteration and 0 on subsequent ones, to indicate the number of items matched and assigned)
So, the loop will add 7 on every iteration, and then divide by the number of iterations, giving a result of 7.

C: Scanf function in for loops runs one more time than it should

In the following code, I want the user to input 10 floating point numbers, and then take the average of them. However, when running it, the user is forced to input 11 numbers, but the 11th one is discarded anyway. The value of the average actually turns out to be correct. I just want to know why the scanf seems to run 1 extra time.
The problem I faced was different than that of the suggested duplicate. Here, the problem was related to my understanding of the scanf function, I actually looped the correct amount of times.
see:
#include <stdio.h>
int main (void)
{
int i;
float entry[10];
float total = 0.0;
printf("please enter 10 floating point numbers\n");
for (i = 0; i < 10; ++i)
scanf("%f\n", &entry[i]);
for (i = 0; i < 10; ++i) {
total = total + entry[i];
}
printf("The average of the 10 floating point numbers is: %f\n", total / 10);
return 0;
}
The \n in the format string is causing that.
Even after 10th element is entered, scanf waits for a non-whitespace character to be entered before it is done. After the 10 numbers have been entered, you can enter any old non-whitespace character to let scanf finish.
Remove the \n from the format string. You don't need it. Use
for (i = 0; i < 10; ++i)
scanf("%f", &entry[i]);
Remove \n inside the scanf i.e. inside the first for loop, write :
scanf("%f",&entry[i]);

Issues with using scanf inside a while loop

I’m brand new to programming. I ‘m working on a homework assignment in order to help us understand scanf and arrays. The program is supposed to ask the user to input an unknown set of numbers. Each set of numbers should be separated by a space like below without hitting enter.
14 15 16
The user can also input numbers on a separate line instead using spaces, but again on the last number inputed the user isn’t supposed to hit enter.
12 13
44 55
5
The user should hit ctrl-d to indicate end of input. The program should display the number of elements entered by the user, along with displaying the numbers the user entered. I have been reading around and think I have a basic concept of how scanf works, but I am still having some difficulty. The code kind of works. However, if the user just enters the numbers on one line they need to hit ctrl-d three times in order for it to exit the loop and display the information.
From what I have found online and understand, I think it’s not working because the user hasn’t hit return, so the input hasn’t been flushed into the stdin. So if I'm understanding correctly, the first time I hit ctrl-d it while flush the input. Then the second time I hit ctrl-d it will finally put the EOF into the stream and the third time it will finally read the -1 produced by the EOF and exit the loop.
Is there anyway to force the input stream once ctrl-d is entered.
#include <stdio.h>
int main()
{
int numbers[20];
int i = 0, count, result, n;
int flag = 0;
printf("Please enter a seiries of numbers:\n");
while (flag == 0)
{
result = scanf("%d", &n); //scan user input into n variable along with getting scanf return value and storing in result variable
printf("result =%i \n", result); //Just printing scanf return value to insure it doing what I think it should be doing
if (result == 1)
{
numbers[i] = n; //if scanf return value is 1 places value of n into first element of array
i++; //used to increment my array
flag = 0;//keeps value of flag equal to 0 in order to stay in loop
}
if(result == -1) //checks to see if result = to -1 should be value returned if cntl +d is entered
{
flag = 1; //sets flag to 1 when cntrl +d is entered in order to exit loop.
}
}
for (count = 0 ; count < i ; count++) //loop to print I which is representing number of user inputs and the actual numbers entered by the user.
{
printf("\ni= %i numbers= %i\n", i, numbers[count]);
}
return 0;
}
I won't give you a solution directly, but will try to help you improve coding in C. The more you work with C the more you will find out that one can write pretty compact code, once the language is mastered.
You can omit flag because it depends on result.
And you could omit result because it is just the return value of scanf.
You can omit n and use numbers array directly.
And you could make use of the preprocessor to use a constant number (often for array sizes as in your case).
Have a look at this. Maybe it helps you get an idea:
#include <stdio.h>
#define COUNT 20
main() {
int numbers[COUNT];
int i;
i = 0;
while (scanf("%d", &numbers[i]) == 1 && i < COUNT)
printf("\t%d\n", numbers[i++]);
return 0;
}
P.S.:
I recommend getting acquainted with the different ways of accessing an array and reading about pointers. The have a very close relationship really.
Address of first element in array : numbers
Access ith element of array : numbers[i]
Equivalently : *(numbers + i)
Another equivalence : *(i+numbers)
Surprise, but equivalent again : i[numbers]
Address of ith element of array : &numbers[i]
K&R is a great resource of information and learning.

getchar not working in switch case (c)

Using a very simple calculator program that prompts a user for an operation to perform, followed by a prompt for two integers on which to perform this operation. The program is supposed to loop after these operations, except in the case where the user enters the character 'q', at which point the program is supposed to quit.
#include <stdio.h>
int main (void)
{
char c;
int number[2], num1, num2, result;
double num1d, num2d, resultd;
int done=1;
while(done)
{
printf("\t What sort of operation would you like to perform? \n \t Type + - * / accordingly. \n");
c = getchar();
printf("\tplease enter a number \n");
scanf("%d",&number[0]);
printf("\tplease enter another number \n");
scanf("%d",&number[1]);
num1 = number[0];
num2 = number[1];
switch(c)
{
case('-'):
result = num1-num2;
printf("\nThe first number you entered subtracted by the second number is %d.\n", result);
break;
case('+'):
result = num1+num2;
printf("The first number you entered added to the second number is %d.\n", result);
break;
case('*'):
result = num1*num2;
printf("The first number you entered multiplied with the second number is %d.\n", result);
break;
case('/'):
num1d = (double) num1;
num2d = (double) num2;
resultd = num1d/num2d;
printf("The first number you entered divided by the second number is %g.\n", resultd);;
break;
case('q'):
printf(" Now Exiting...\n");
done=0;
break;
default:
puts("Invalid key pressed. Press q to exit");
break;
}
}
return 0;
}
Works correctly for a single calculation, but subsequently performs oddly; in particular it prints
printf("\t What sort of operation would you like to perform? \n \t Type + - * / accordingly. \n");
printf("\tplease enter a number \n");
altogether.
The standard method of clearing the input buffer while (getchar() != '\n'); doesn't fix this. One out of two times that this text displays incorrectly the user can still use the program as if the instructions were displaying as they should (so the user can type an operation such as +, carriage return, and then some integer and a carriage return, and the program will perform correctly from that point on) Every other time however the program will put "Invalid key pressed. Press q to exit" regardless of input.
What everyone else here is saying is true, getchar() returns an int but that's not your problem.
The problem is that getchar() leaves a newline character after you use it. If you're going to use getchar() you must always consume the newline char afterwards. This simple fix:
printf("\t What sort of operation would you like to perform? \n \t Type + - * / accordingly. \n");
c = getchar();
getchar(); //<-- here we do an extra getchar for the \n
printf("\tplease enter a number \n");
scanf("%d",&number[0]);
printf("\tplease enter another number \n");
scanf("%d",&number[1]);
and that will eliminate the problem. Every time you type <somechar><enter> it's really putting two characters on the buffer, for example if I hit + and enter I'm getting:
'+''\n' // [+][\n]
getchar() will only get the first of these, then when getchar() is called again it won't wait for your input it will just take that '\n' and move on to the scanf()
You shouldn't mix character-by-character with more high-level input functions such as scanf(). It's better to use scanf() to input the command character too, but of course then you will have to press enter after the command. I believe this it the root cause of your problems.
As an aside, note that getchar(), despite it's name, returns int, not char. This is because it can return EOF which is a special constant whose value is different from that of all characters.
Further, you should always check the return value of I/O functions like scanf(), they can fail if the input doesn't match the pattern string.
As a debugging hint, you can of course print the value of c before interpreting it, so you can easier see and understand the flow of the program.
I'm guessing it works the first time, but not the next time. This is because the scanf calls leaves the newline in the input buffer so the next time getchar is called in the loop it will return the newline character. Add a space after the format in the scanf calls
scanf("%d ",&number[0]);
and it will discard remaining whitespace from the buffer.
Use a debugger to step through the code and check the variables to verify.
Your getchar should return int. The reason is as below
getchar reads characters from the program's standard input
and returns an int value suitable for storing into a char.
The int value is for one reason only: not only does getchar
return all possible character values, but it also returns an
extra value to indicate that end-of-input has been seen.
The range of a char might not be enough to hold this extra value,
so the int has to be used.
So basically you need to change char c to int c in your code

Resources