C won't finish reading the program after while loop - c

Everytime I try to press Ctrl-Z the while loop it won't print out the average.
#include <stdio.h>
int main(void)
{
float a;
float b = 0;
int counter = 0;
while(1){
scanf("%f", &a);
b += a;
counter++;
}
float average = b/counter;
printf("%f", average);
return 0;
}

If you're in Linux and expect Ctrl+Z to finish the input, you're mistaken. It's Ctrl+D, but it's Ctrl+Z in Windows though.
(What Ctrl+Z does in Linux is generally (in Bash and other shells) to suspend the program, meaning it's temporarily stopped but still exists as a process.)
You should change your loop to something like:
while(scanf("%f", &a) == 1)
{
b += a;
++counter;
}
and then try again with the EOF keyboard sequence (or just some non-numeric input).

Because there is no condition to break out (terminate) the loop, i.e, this is an infinite loop.
Try this instead:
while(1){
if(scanf("%f", &a) == 1)
{
b += a;
counter++;
}
else break;
}
}
Now, pressing Ctrl+Z (as you mentioned in the question) will terminate the loop.

Rule of thumb:
NEVER use an endless loop without making sure you have a hitable break statement.
#include <stdio.h>
int main(void)
{
float a;
float b = 0;
int counter = 0;
while(1){
if(scanf("%f", &a) == 1)
{
b += a;
counter++;
}
else break;
}
float average = b/counter;
printf("%f", average);
return 0;
}

instead of while(1), you need to test for eof().
Try while(scant("%f", &a) == 1)
see the man page for scant() and see what it says about return values, at the bottom.

Your control Z is affecting the entire program, since it is inside the loop when you hit cntrl-Z the final section never executes.

Related

Why does my program print something before it ends when I press ctrl + D?

So I wrote a simple program that converts a decimal to binary, that only accepts positive whole numbers. So numbers like -2 and 1.1 would output "Sorry, that's not a positive whole number." It infinitely asks the user to input a number until the user presses ctrl + D. However when I tested it it prints out the "Sorry..." statement before it ends the program.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
void DecToBin(int userInput){
int binary[32];
int i = 0;
while (userInput > 0) {
binary[i] = userInput % 2;
userInput /= 2;
i++;
}
for (int j = i - 1; j >= 0; --j) {
printf("%d", binary[j]);
}
}
int main(void) {
double userDec;
int temp;
printf("Starting the Decimal to Binary Converter!\n\n");
while(!feof(stdin)) {
printf("Please enter a positive whole number (or EOF to quit): ");
scanf("%lf", &userDec);
temp = (int)(userDec);
if ((userDec > 0) && (temp / userDec == 1)) {
printf("\n\t%.0lf (base-10) is equivalent to ", userDec);
DecToBin(userDec);
printf(" (base-2)!\n\n");
}
else {
printf("\tSorry, that was not a positive whole number.\n");
}
}
printf("\n\tThank you for using the Decimal to Binary Generator.\n");
printf("Goodbye!\n\n");
return 0;
}
(All the tab and newlines are just how it's supposed to be formatted so don't pay attention to that)
So from what I'm understanding, my program reads ctrl + D as the else in my while loops. So, any idea why that is?
It seems like you think C-d would trigger some kind of break in the code. Like the keyword break. This is not true.
Read this post to see what's happening when you press C-d: https://stackoverflow.com/a/21365313/6699433
That does not cause anything special to happen in the C code. scanf will simply not read anything. After the scanf statement, the code will continue as usual, so the code WILL unconditionally enter the if statement.
This is also a pretty severe thing, because you'll be using userDec uninitialized. scanf returns the number of successful assignments, and you should always check the return value. So in your case you want this:
if(scanf("%lf", &userDec) != 1) { /* Handle error */ }
Because if scanf does not return 1, userDec is unassigned.
To achieve what you want, simply do this:
if(scanf("%lf", &userDec) != 1)
break;

Check to see if scanf is not a float

#define maximum 100
#include <math.h>
#include <stdio.h>
int main () {
float sum, mean, variance, difference;
float sumforvariance, standarddev;
sumforvariance=0;
sum=0;
mean=0;
variance=0;
difference=0;
standarddev=0;
int a, count, b, c;
float insertnum[maximum]
for (a=0; a<maximum; a++) {
scanf("%f",&insertnum[a]);
count ++;
if (insertnum[a]==35.00) {
if (count==1) {
printf ("no data\n");
return 0;
}
break;
}
}
for (b=0; b<count; b++) {
sum+=insertnum[b];
}
mean=sum/count;
for (c=0; c<count; c++) {
difference=insertnum[c]-mean;
sumforvariance=sumforvariance+pow(difference,2);
}
variance=variance/count;
standarddev=sqrt(variance);
printf("mean: %f",mean);
printf("standdev: %f",standarddev);
Hi so I have a simple question. I am trying to calculate a standard deviation and mean for a set of numbers like this
./a.out 12 20 30 etc #
The # is to terminate inputing more numbers. As you can see in the first for loop, I am trying to input the numbers from standard output into an array of floats. The problem is when I enter 35, I do not want to terminate inputting more numbers because its not equal to #. How am I able to enter 35 and continue to enter more numbers until I enter # since they both contain the same numerical value. #=35 and 35=35.
Read you user input in as a string. Sniff for the terminating condition, then convert from string to float. Using the helper function, strtof which is available from #include <stdlib.h>
#define maximum 100
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
int main() {
float sum, mean, variance, difference;
float sumforvariance, standarddev;
sumforvariance = 0;
sum = 0;
mean = 0;
variance = 0;
difference = 0;
standarddev = 0;
int a, count=0, b, c;
float insertnum[maximum];
for (a = 0; a < maximum; a++) {
char userinput[101] = {0};
userinput[0] = '\0';
scanf("%100s", userinput);
if (userinput[0] == '#')
{
break;
}
insertnum[count] = strtof(userinput, nullptr);
count++;
}
return 0;
}
Also, you forgot to initialize count. And your code was inserting the # read into the array as well. So I fixed that for you.
Aside - I'll never forget the day my computer science professor passionately screamed to the class about the dangers of "reading numbers" from input. Users type characters with the keyboard not numbers. Hence, "validating input" became engrained with me to this day. You might want to consider just letting your loop break whenever the user types anything not a number. A modified version of the loop as follows:
for (a = 0; a < maximum; a++) {
char userinput[101] = {0};
userinput[0] = '\0';
scanf("%100s", userinput);
char* endptr = NULL;
float f = strtof(userinput, &endptr);
if (userinput == endptr)
{
// whatever was typed was not a float
break;
}
insertnum[count] = f;
count++;
}
Check the return value of scanf -- when it successfully converts a float it will return 1 (or more generally, however many conversions in the format string succeeded). So when the input is #, it will return 0 (nothing converted) and leave the # on in the input stream. You can then check the next character to make sure its a #. So you end up with a loop like:
for (a=0; a<maximum && scanf("%f",&insertnum[a]) == 1; a++) {
++count;
}
or even
for (count=0; count < maximum && scanf("%f",&insertnum[count]) == 1; ++count);
if (count == maximum) {
// read the limit -- may be more data
} else {
if (getchar() == '#') {
// got the expected terminator
} else {
// something else caused a problem

C Program - Do - while loops not working

My target output is after users entering a number >2 & <20 (result show) then program continue asking users enter another number. Or if users enters number <=2 or >=20, it will not show result but just re-asking users to enter number.
My Current Output: If I input number <=2 || >=20, it will re-ask. but if I enter number between 2 and 20. It will just stops which suppose to be keep asking for entering new numbers.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX 20
int main(void)
{
unsigned int random_array[MAX][MAX];
unsigned int r, c, x, y;
do {
printf("Number Matrix in array ? ");
scanf("%d", &c);
system("cls");
r = c;
if (c>2 && c<20) {
r = c;
for (x = 0; x <= r - 1; ++x)
{
for (y = 0; y <= c - 1; ++y)
{
random_array[x][y] = -1;
}
}
for (x = 0; x <= r - 1; ++x)
{
for (y = 0; y <= c - 1; ++y)
{
if (x == y)
random_array[x][y] = 0;
else
if (x<y)
random_array[x][y] = 1;
printf("%4d", random_array[x][y]);
}
puts("");
}
system("pause");
}
} while (c<=2 || c >=20);
return 0;
}
Since you want to prompt the user for input regardless of what they last input, you probably need an infinite loop. For this, replace your line with the while condition to this:
} while (1);
This basically tells your program to loop infinitely.
Your codes
do
{
// show something
} while (c<=2 || c >=20);
means that it will stop after showing something if (c > 2 && c < 20), and that is exactly why your program quits after the condition is met.
To achieve your goal, consider using an infinite loop, and do different things using if-else inside the loop.
printf("Number Matrix in array ? ");
scanf("%d", &c);
system("cls");
if (c<=2 || c >=20)
{
continue;
}
else
{
// show something
}
The while condition should be while(c>2&c<20). But if you enter a number <=2 or >=20 the program will end and will not ask you for an input anymore. So the solution would be to use an infinite while loop and use break to end the loop when you want by using a condition.
A do-while loop will run the block of code once, then will repeat until the while conditional evaluates to false.
do{
//Stuff
}while (c > 20 || c < 2);
That would do the //Stuff part once, then it would do it again until c is either greater than 20 or less than 2.
What you want to do is surround the entire thing in an infinite loop, (either for(;;) or while(1)) so that it continues regardless.
But you also want to validate the input, so that's when you could use a do-while loop. When you're getting the scanf, you could do something like:
do{
printf("Enter c: ");
scanf("%d", &c);
}while (c > 20 or whatever);
Then you could make him keep putting in c until it's the desired input!
Hope this helps.
EDIT: Here's an example of putting the do-while inside the while:
while(1){
do{
printf("Enter a positive number: ");
scanf("%d", &aNum);
}while(aNum < 0);
printf("Your positive number is %d.\n", aNum);
}
That would ask a user for input, and if he puts in a negative number it would ask him again. If it's a positive number it would print, then go back to the start and ask him for an input again.

How do I stop making this C code loop? [duplicate]

This question already has answers here:
Why is scanf() causing infinite loop in this code?
(16 answers)
Closed 6 years ago.
I have written some C code where you can pick from an answer by inputting a 1 or 2, and if you input a higher number it will bring you back to pick another number just fine. However, if I try to input something that's not a value or a number, like a string or character, the error message at the bottom will repeat infinitely. How can I make my code act the same as if you input a higher number than 1 or 2 when you input any other character? Here the code I use abstracted:
#include <stdio.h>
int a;
int main(){
b:scanf("%d", &a);
if(a==1)
{
a=0;
}
if(a==2)
{
a=0;
}
else
{
a=0;
printf("\nERROR: Please try again.\n\n");
goto b;
}
}
EDIT: Apparently the return value is still stuck in scanf() when it returns to it. How can I clear out scanf() of its return value?
Don't use gotos at all. Instead use while loops:
#include <stdio.h>
int main(void) {
int a, end = 1; //end determines if the loop should end
do { //a do-while loop - it's the same as a while loop, except it runs atleast once
scanf("%d", &a);
switch (a) { //switches the value of a
case 1:
case 2: printf("You entered %d\n", a);
end = 0; //sets end to 0, which will end the loop(see below)
break;
default: printf("\nERROR: Please try again.\n\n");
}
} while (end); //every non-zero value is true, so when I set end to 0, it will end the loop
return 0; //don't forget the return 0: it shows you that your program ran without error
}
So I wrote it that it ends as soon as you type a valid input. You also don't need to set a to zero, as you read it in again every time you run the loop.
EDIT: if you want to check for invalid input such as 5x, you can use the following:
int check, var, error;
char ch;
do {
error = 0;
check = scanf("%d%c", &var, &ch);
if (check != 2 || ch != '\n') {
printf("Wrong input. Try again -> ");
error = 1;
fflush(stdin);
}
} while (error);
#include <stdio.h>
int a;
int isNumeric(const char *str)
{
while(*str != '\0')
{
if(*str < '0' || *str > '9')
return 0;
str++;
}
return 1;
}
int main(){
char inputStr[10];
while(1){
scanf("%9s",inputStr);
if(!isNumeric(inputStr)){
a=0;
printf("\nERROR Not a number: Please try again.\n\n");
}else {
a = atoi(inputStr);
if(a==1){
a = 0;
}else if(a == 2){
a == 0;
}else{
a=0;
printf("\nERROR : Please try again.\n\n");
}
}`enter code here`
}
}
Have not tested. But I guess you will get a good idea. check strtol function. That is also useful.
Something like...
Note: Obviously 999 is an arbitrary value. Just chosen to give you an example.
#include <stdio.h>
int main(){
int a = 1;
while (a != 999){
scanf("%d", &a);
if(a==1)
{
a=0;
}
if(a==2)
{
a=0;
}
else if (a != 999)
{
a=0;
printf("\nERROR: Please try again.\n\n");
}
} // while()
} // main()

End while loop with ctrl+d, scanf?

I want the user to be asked "how many circles" they wanna write until the user decides to end it with (Ctrl+d) which is EOF?
extra question: if I write a letter for example "k" it will spam out circles. How do I change that?
#include <stdio.h>
int main ()
{
int i;
int x;
printf("\nHow many circles do you want to write?\n");
scanf("%d", &x);
while(x != EOF)
{
for (i = 1; i <= x; i = i + 1)
{
putchar('o');
}
printf("\nHow many circles do you want to write?"
"(to end program click ctrl+d at the same time!))\n");
scanf("%d", &x);
}
printf("\n\n Bye! \n\n");
return 0;
}
The biggest problem with your program is that scanf will not read an EOF into a variable. However, fixing just this problem is not going to make your program entirely correct, because there are other issues in your code:
Your code repeats itself - when possible, you should unify the code that deals with the first iteration vs. subsequent iterations.
Your code will not handle invalid input - when an end-user enters non-numeric data, your program goes into an infinite loop.
Your code follows the old style of C - declaring all variables at the top has not been required for more than fifteen years. You should declare your loop variable inside the loop.
Here is how you fix all these shortcomings:
int x;
for (;;) {
printf("\nHow many circles do you want to write? (to end the program click Ctrl+D at the same time!)\n");
int res = scanf("%d", &x);
if (res == EOF) break;
if (res == 1) {
... // Draw x circles here
} else {
printf("Invalid input is ignored.\n");
scanf("%*[^\n]");
}
}
printf("\n\n Bye! \n\n");
return 0;
As per the man page, scanf() will return EOF, not scan EOF to x as a value.
Return Value
These functions return the number of input items successfully matched and assigned, which can be fewer than provided for, or even zero in the event of an early matching failure.
The value EOF is returned if the end of input is reached before either the first successful conversion or a matching failure occurs......
Also,
if I write a letter for example "k" it will spam out circles, how do I change that?
In case of input of one char value, it causes matching failure, in your case, scanf() returns 0, instead of 1.
So, altogether, you've to collect the return value of scanf() and check check that value for the required condition. You can change your code as
int retval = 0;
while ((retval = scanf("%d", &x))!= EOF && (retval == 1))
if you're allowed to #include , there are two convenient functions bool kbhit() and char getch().
So you can write
char c=0;
if(kbhit()) c = getch();
if(c== whatever code ctrl+d returns) x=EOF;
Hint: Take a look at what scanf(%d,&x) returns when you enter a letter instead of a number.
You can read char by char input :
#include <stdio.h>
int main ()
{
int i;
int x = 0;
int nb = 0;
while(x != EOF)
{
printf("\nHow many circles do you want to write?\n");
nb = 0;
for (x = getchar(); x != '\n'; x = getchar()) {
if (x == EOF)
goto end;
if (x >= '0' && x <= '9') {
nb = nb * 10 + x - '0';
}
}
for (i = 0; i < nb; i++)
{
putchar('o');
}
}
end:
printf("\n\n Bye! \n\n");
return 0;
}

Resources