I have to write a do while loop that reads integers and computes their sum. It continues to add the integers until the user enters -1, but the -1 should not be added to the sum.
do
{
printf("Enter a number. Enter -1 to stop\n");
scanf(" %d", &n);
sum = sum + n;
printf("The sum is %d\n", sum);
}
while (n >= 0);
{
return 0;
printf("Have a nice day!\n");
}
Where am I going wrong? How do I get the -1 to avoid being added to the sum?
You need to declare n, i before use. And you need a break when detecting input -1.
int sum = 0, n = 0;
do
{
printf("Enter a number. Enter -1 to stop\n");
scanf("%d", &n);
if( -1 == n )
break; // <-- break here to get out the loop
sum = sum + n;
printf("The sum is %d\n", sum);
} while (1); // <-- note while(1) should be used instead of while(n >= 0), this makes sure your loop only exits when detecting input -1
Also there's no point adding a printf after you return - ie this code can be removed:
{
return 0;
printf("Have a nice day!\n"); // <-- any code after `return` is meaningless
}
There are a couple of ways to avoid having -1 added to the sum. Let's look at your code, first:
do
{
printf("Enter a number. Enter -1 to stop\n");
scanf(" %d", &n);
sum = sum + n;
printf("The sum is %d\n", sum);
}
while (n >= 0);
The do/while loop will exit if n is less than zero. This is one way to catch the -1 as a sentinel value, so no problem there.
Unfortunately, your code reads the number, adds it to the total, and then checks if it should stop. With that order, you always add before checking.
The most obvious, brute-force way to avoid adding the number is to add an explicit check:
do {
printf ... scanf ... ;
if (n != -1)
sum = sum + n;
} while (n >= 0);
Another way is to cheat. Given that -1 always comes at the end of the list, just undo that at the end:
do {
printf... scanf...;
sum = sum + n;
} while (n >= 0);
sum = sum - n; // CHEAT - just subtract out the last number
printf("The sum is %d\n", sum);
Finally, there is a trick you can use. Sometimes in these situations, you can "shift" the loop, so that you actually do things slightly out of order. In this case, you would like to test before you add. So put the add at the top of the loop, and just set things up so that the very first add is harmless:
n = 0; // X + 0 is X, so adding 0 is harmless.
do {
sum = sum + n;
printf ... scanf ...;
} while (n >= 0);
This may make you uncomfortable for a minute, but it's an idiom you'll see a lot. The loop code has been "twisted" inside the loop, so that the top of the "natural" loop does not start at the top of the actual loop body. It's a good trick to know.
The behavior of your do-while loop will be clearer if you think of it in terms of the GOTOs the compiler sees it as:
// prior code before here...
START_OF_DO:
printf("Enter a number. Enter -1 to stop\n");
scanf(" %d", &n);
sum = sum + n;
printf("The sum is %d\n", sum);
if ( n >= 0 ) {
goto START_OF_DO; // this is what "while (n >= 0);" does
}
return 0;
printf("Have a nice day!\n"); // <-- note that this will never print, because you have already returned
Formed this way, you can see that your sum = sum + n happens before you check if ( n >= 0).
(note I am not suggesting that you ever use goto! But sometimes it's helpful to see these things in terms of the machine instructions the compiler emits.)
You're overwriting the value of n before it checks the condition to run the loop again.
Make these changes and it should work now.
int input = 0; // Change
int n = 0; // Change
do
{
printf("Enter a number. Enter -1 to stop\n");
scanf(" %d", &input); // Change
if(input >=0 ) // Change
{
n = input; // Change
sum = sum + n;
printf("The sum is %d\n", sum);
}
}
while (input != -1); // Change
{
return 0;
printf("Have a nice day!\n");
}
Related
Something is wrong. I'm trying to make a cade which can count number count of any natural number. Like number count of 2 is 1, 30 is 2, 456 is 3. My code is running for 1 digit numbers but not for two digit numbers.
#include<stdio.h>
void main(void)
{
int num,count,check;
float div;
printf("Enter a natural number\n");
scanf("%d", &num);
while (num<=0)
{
printf("Error\n");
printf("Enter a number\n");
scanf("%d", &num);
}
while(num>1)
{
count=1;
check=10;
div=num/check;
if(div<=1)
{
printf("Number count is\n%d", count);
break;
}
check = check*10;
count = count+1;
}
}
The problem with your solution is that after check and count are modified at the end of the loop, they are re-declared to 1 and 10 respectively at the beginning of the loop at every passage.
You need to move the declaration just before the while loop.
Also div doesn't need to be a float given that the decimal part of this number is irrelevant.
You could also use less variables by replacing check by 10 and
using num directly instead of temporarily storing results in div.
I think this might be a simpler solution
#include <stdio.h>
int main(){
int num = 0, digits = 0;
while (num <= 0)
{
printf("Enter a natural number\n");
scanf("%d", &num);
num == 0 ? printf("Error\n") : 0;
}
for( ; num > 0; digits++)
num /= 10;
printf("number of digits: %d\n", digits);
}
As num is continuously divided by 10, the decimal of the result gets truncated since num is an int while digits steadily increases.
It is time to learn to use a debugger. Using it would have immediately shown the major problem in your code: you reset the value of count and check inside the loop. So if you enter a number greater or equal to 10, you enter an infinite loop because you will consistently divide that number by 10 and find that the result is >= 1!
There is another less important problem: you use if(div<=1) when it should be if(div<1). Because 10/10 is 1 and has 2 digits...
After those fixes you should have:
...
check = 10;
count = 1;
while (num > 1)
{
div = num / check;
if (div < 1)
{
printf("Number count is\n%d", count);
break;
}
check = check * 10;
count = count + 1;
}
return 0; // main shall return an int value to its environment...
}
Which correctly gives the number of decimal digit on positive integers. But as you were said in comments, you should always test the return value of scanf (what is the user inadvertently types a t instead of 5 for example?).
That being said, this answer intends to show you what the problems were, but Keyne's solution is better...
Hello I have a small problem with my code and I want to understand it. My task is to write a program that take the sum and average for n numbers with while loops or nested while loops with if conditions, when you want to exit the code you should enter -1. The code is down below. The problem I have is that I can't get it to exclude the -1 from the calculation. What am I doing wrong. And it is suppose to be a simple code.
int main(void) {
int count;
float sum, average, number;
sum = 0;
count = 0;
printf("Calculate sum and average (-1 to quit)\n");
while (number!=-1) {
scanf("%f", &number);
sum = sum + number;
count = count + 1;
}
average = sum / count;
printf("Sum=%f", sum);
printf(" Average=%f", average);
}
in the while block, you read the number and then add it to your average calculation, and only then after the iteration repeats you're checking if it's different than -1 to stop the iteration:
there are obviously different ways to solve it:
one way can be to use while(true) and in the while block after you read the number add an if statement to compare it with -1 and break out of the loop
while (true) {
scanf("%f", &number);
if (number == -1) break;
sum = sum + number;
count = count + 1;
}
Reordering the different steps could solve this:
int main(void) {
int count;
float sum, average, number=0.0f;
sum = 0;
count = -1;
printf("Calculate sum and average (-1 to quit)\n");
while (number!=-1) {
sum = sum + number; // first time no effect with 0
count = count + 1; // first time "no effect" counting to 0
scanf("%f", &number); // will not be counted or summed if -1
}
average = sum / count;
printf("Sum=%f", sum);
printf(" Average=%f", average);
}
Think it through with immediatly entered -1:
sum is 0+0, suitable for no numbers being added up
count is -1+1==0, suitable for no numbers
dividing by 0 should be avoided, but that is a separate issue
Think it through with one number:
number is read in with sum==0 and count==0
is not -1, so loop iterates again
sum and count are updated meaningfully
-1 one is entered
loop ends without processing -1
By the way, comparing a float for identity is risky. You would be safer if you could compare more "generously", e.g. while (number>-0.5).
I think you should take the input at the last of the loop as it will get check in the next iteration. And when -1 comes up it will not be added.
#include <stdio.h>
int main(){
int count=0;
float sum=0, average=0, number=0;
printf("Calculate sum and average (-1 to quit)\n");
while(number!=-1){
sum = sum + number;
count = count + 1;
scanf("%f", &number);
}
average = sum / count;
printf("Sum=%f", sum);
printf(" Average=%f", average);
}
Code needs to test number as -1 before including it in the summation. OP's code test almost does this right. OP's code test for -1 before number is even assigned leading to undefined behavior (UB).
float number;
while (number!=-1) { // UB!
Also good to test the return code of scanf() for success.
while (scanf("%f", &number) == 1 && number != -1) {
sum = sum + number;
count = count + 1;
}
I'm getting a consistent divide by zero error, even though each loop should be populating the variables. Code below:
#include <stdio.h>
void calculateAverage()
{
int grade, count, sum;
double average;
sum = 0;
count = 0;
grade = 0;
average = 0.0;
int coolvalue = 0;
while (coolvalue==0)
{
scanf("%d", &grade);
if (grade == -1)
{
sum, sizeof(double);
count, sizeof(double);
average = (sum / count);
printf("%lf", &average);
break;
}
else
{
if ((grade > 100) || (grade < -1))
{
printf("Error, incorrect input.\n");
break;
}
else
{
sum = +grade;
count = count + 1;
return count;
return sum;
}
}
}
coolvalue = 1;
}
int main(void)
{
while (1)
calculateAverage();
while (1) getchar();
return 0;
}
Even while using return, I'm not able to properly increment the value of sum or count.
There are multiple issues in your code.
scanf("%d", &grade); - you don't check the value returned by scanf(). It returns the number of values successfully read. If you enter a string of letters instead of a number, scanf("%d") returns 0 and it does not change the value of grade. Because of this the code will execute the rest of the loop using the previous value of grade. You should restart the loop if the value returned by scanf() is not 1:
if (scanf("%d", &grade) != 1) {
continue;
}
Assuming you enter 10 for grade this block of code executes:
sum = +grade;
count = count + 1;
return count;
return sum;
sum = +grade is the same as sum = grade. The + sign in front of grade doesn't have any effect. It is just the same as 0 + grade.
You want to add the value of grade to sum and it should be sum += grade. This is a shortcut of sum = sum + grade.
return count makes the function complete and return the value of count (which is 1 at this point) to the caller. The caller is the function main() but it doesn't use the return value in any way. Even more, your function is declared as returning void (i.e. nothing) and this renders return count incorrect (and the compiler should warn you about this).
return sum is never executed (the compiler should warn you about it being dead code) because the function completes and the execution is passed back to the caller because of the return count statement above it.
Remove both return statements. They must not stay here.
If you enter -1 for grade, this block of code is executed:
sum, sizeof(double);
count, sizeof(double);
average = (sum / count);
printf("%lf", &average);
break;
sum, sizeof(double) is an expression that does not have any effect; it takes the value of sum then discards it then takes the value of sizeof(double) (which is a constant) and discards it too. The compiler does not even generate code for it.
the same as above for count, sizeof(double);
average = (sum / count);:
the parenthesis are useless;
because both sum and count are integers, sum / count is also an integer (the integral result of sum / count, the remainder is ignored).
you declared average as double; to get a double result you have to cast one of the values to double on the division: average = (double)sum / count;
if you enter -1 as the first value when the program starts, count is 0 when this code is executed and the division fails (division by zero).
printf("%lf", &average); - you want to print the value of average but you print its address in memory. Remove the & operator; it is required by scanf() (to know where to put the read values). It is not required by printf(); the compiler generates code that passes to printf() the values to print.
break; - it passes the execution control after the innermost switch or loop statement (do, while or for). It is correct here and makes the variable coolvalue useless. You can simply remove coolvalue and use while (1) instead.
All in all, your function should look like:
void calculateAverage()
{
int sum = 0;
int count = 0;
int grade = 0;
double average = 0.0;
while (1) {
if (scanf("%d", &grade) != 1) {
// Invalid value (not a number); ignore it
continue;
}
// A value of -1 signals the end of the input
if (grade == -1) {
if (count > 0) {
// Show the average
average = (double)sum / count;
printf("Average: %lf\n", average);
} else {
// Cannot compute the average
puts("You didn't enter any value. Cannot compute the average.\n");
}
// End function
return;
}
if ((grade < -1) || (100 < grade)) {
puts("Error, incorrect input.\n");
// Invalid input, ignore it
continue;
}
sum += grade;
count ++;
}
}
Quite a few corrections need to be made.
The while loop in the calculateAverage() function. That's an infinite loop buddy, because you are not changing the value of that coolValue variable anywhere inside, instead you make it 1 only when it exits the loops, which it never will.
So, use while(1) {...}, and inside it, check for the stopping condition, i.e, if (grade == -1) { ... } and inside it calculate and print the average and return. This will automatically break the while.
You're not checking if the input grade is actually a valid integer or not. Check the value of scanf for that, i.e, use if (scanf("%d", &grade) != 1) { ... }
The expression sum = +grade; is just another way of writing sum = 0+grade which in turn is nothing but sum = grade. Replace this with sum += grade;. This is the right way to write a shorthand for addition.
Two return statements..a very wrong idea. First of all, a function can have just one return(in an obvious way I mean, at once). Secondly, the function calculateAverage() is of return-type void. there's no way how you can return double value from it. So remove these two statements.
I have attached the code below which works. Also do go through the output which I have attached.
CODE:
#include <stdio.h>
void calculateAverage()
{
int grade, count = 0, sum = 0;
double average;
printf("\nenter the grades... enter -1 to terminate the entries\n.");
while (1) {
printf("\nEnter the grade: ");
if (scanf("%d", &grade) != 1) {
printf("\nInvalid characters entered!!!");
continue;
}
else if(((grade > 100) || (grade < -1))) {
printf("\nInvalid grade entered!!!");
continue;
}
else {
if (grade == -1) {
average = sum/count;
printf("\nAverage value of grades: %.3lf",average);
return;
}
else {
sum += grade;
count++;
}
}
}
}
int main(void)
{
calculateAverage();
return 0;
}
OUTPUT:
enter the grades... enter -1 to terminate the entries.
Enter the grade: 50
Enter the grade: 100
Enter the grade: 60
Enter the grade: -1
Average value of grades: 70.000
Perhaps it is better for the function to be of type double instead of void. Although it is not my favorite solution it is close to what you want.
#include <stdio.h>
double calculateAverage(void)
{
double average;
int sum = 0, count=0, grade;
while (1)
{
scanf("%d", &grade);
if ((grade > 100) || (grade < -1))
printf("Error, incorrect input.\n");
else if (grade != -1)
{sum = sum+ grade; count = count + 1;}
else
break;
}
if (count==0)
average=-1.0; //none valid input. Notify the main()
else
average=(double)sum/count;
return average;
}
int main(void)
{
double result;
result= calculateAverage();
if (result!=-1.0)
printf("\n average= %lf",result);
else
printf("No grades to calculate average");
getchar();
return 0;
}
Even though this question has been asked a million times I just haven't found an answer that actually helps my case, or I simply can't see the solution.
I've been given the task to make a program that takes in a whole number and counts how many times each digit appears in it and also not showing the same information twice. Since we're working with arrays currently I had to do it with arrays of course so since my code is messy due to my lack of knowledge in C I'll try to explain my thought process along with giving you the code.
After entering a number, I took each digit by dividing the number by 10 and putting those digits into an array, then (since the array is reversed) I reversed the reverse array to get it to look nicer (even though it isn't required). After that, I have a bunch of disgusting for loops in which I try to loop through the whole array while comparing the first element to all the elements again, so for each element of the array, I compare it to each element of the array again. I also add the checked element to a new array after each check so I can primarily check if the element has been compared before so I don't have to do the whole thing again but that's where my problem is. I've tried a ton of manipulations with continue or goto but I just can't find the solution. So I just used **EDIT: return 0 ** to see if my idea was good in the first place and to me it seems that it is , I just lack the knowledge to go back to the top of the for loop. Help me please?
// With return 0 the program stops completely after trying to check the digit 1 since it's been checked already. I want it to continue checking the other ones but with many versions of putting continue, it just didn't do the job. //
/// Tried to make the code look better. ///
#include <stdio.h>
#define MAX 100
int main()
{
int a[MAX];
int b[MAX];
int c[MAX];
int n;
int i;
int j;
int k;
int counter1;
int counter2;
printf("Enter a whole number: ");
scanf("%i",&n);
while (1)
{
for (i=0,counter1=0;n>10;i++)
{
a[i] = n%10;
n=n/10;
counter1+=1;
if (n<10)
a[counter1] = n;
}
break;
}
printf("\nNumber o elements in the array: %i", counter1);
printf("\nElements of the array a:");
for (i=0;i<=counter1;i++)
{
printf("%i ",a[i]);
}
printf("\nElements of the array b:");
for (i=counter1,j=0;i>=0;i--,j++)
{
b[j] = a[i];
}
for (i=0;i<=counter1;i++)
{
printf("%i ",b[i]);
}
for (i=0;i<=counter1;i++)
{
for(k=0;k<=counter1;k++)
{
if(b[i]==c[k])
{
return 0;
}
}
for(j=0,counter2=0; j<=counter1;j++)
{
if (b[j] == b[i])
{
counter2+=1;
}
}
printf("\nThe number %i appears %i time(s)", b[i], counter2);
c[i]=b[i];
}
}
The task at hand is very straightforward and certainly doesn't need convoluted constructions, let alone goto.
Your idea to place the digits in an array is good, but you increment counter too early. (Remember that arrays in C start with index 0.) So let's fix that:
int n = 1144526; // example number, assumed to be positive
int digits[12]; // array of digits
int ndigit = 0;
while (n) {
digits[ndigit++] = n % 10;
n /= 10;
}
(The ++ after ndigit will increment ndigit after using its value. Using it as array index inside square brackets is very common in C.)
We just want to count the digits, so reversing the array really isn't necessary. Now we want to count all digits. We could do that by counting all digits when we see then for the first time, e.g. in 337223, count all 3s first, then all 7s and then all 2s, but that will get complicated quickly. It's much easier to count all 10 digits:
int i, d;
for (d = 0; d < 10; d++) {
int count = 0;
for (i = 0; i < ndigit; i++) {
if (digit[i] == d) count++;
}
if (count) printf("%d occurs %d times.\n", d, count);
}
The outer loop goes over all ten digits. The inner loop counts all occurrences of d in the digit array. If the count is positive, write it out.
If you think about it, you can do better. The digits can only have values from 0 to 9. We can keep an array of counts for each digit and pass the digit array once, counting the digits as you go:
int count[10] = {0};
for (i = 0; i < ndigit; i++) {
count[digit[i]]++;
}
for (i = 0; i < 10; i++) {
if (count[i]) printf("%d occurs %d times.\n", i, count[i]);
}
(Remember that = {0} sets the first element of count explicitly to zero and the rest of the elements implicitly, so that you start off with an array of ten zeroes.)
If you think about it, you don't even need the array digit; you can count the digits right away:
int count[10] = {0};
while (n) {
count[n % 10]++;
n /= 10;
}
for (i = 0; i < 10; i++) {
if (count[i]) printf("%d occurs %d times.\n", i, count[i]);
}
Lastly, a word of advice: If you find yourself reaching for exceptional tools to rescue complicated code for a simple task, take a step back and try to simplify the problem. I have the impression that you have added more complicated you even you don't really understand instead.
For example, your method to count the digits is very confused. For example, what is the array c for? You read from it before writing sensible values to it. Try to implement a very simple solution, don't try to be clever at first and go for a simple solution. Even if that's not what you as a human would do, remeber that computers are good at carrying out stupid tasks fast.
I think what you need is a "continue" instead of a return 0.
for (i=0;i<=counter1;i++) {
for(k=0;k<=counter1;k++) {
if(b[i]==c[k]) {
continue; /* formerly return 0; */
}
for(j=0,counter2=0; j<=counter1;j++)
if (b[j] == b[i]){
counter2+=1;
}
}
Please try and see if this program can help you.
#include <stdio.h>
int main() {
unsigned n;
int arr[30];
printf("Enter a whole number: ");
scanf("%i", &n);
int f = 0;
while(n)
{
int b = n % 10;
arr[f] = b;
n /= 10;
++f;
}
for(int i=0;i<f;i++){
int count=1;
for(int j=i+1;j<=f-1;j++){
if(arr[i]==arr[j] && arr[i]!='\0'){
count++;
arr[j]='\0';
}
}
if(arr[i]!='\0'){
printf("%d is %d times.\n",arr[i],count);
}
}
}
Test
Enter a whole number: 12234445
5 is 1 times.
4 is 3 times.
3 is 1 times.
2 is 2 times.
1 is 1 times.
Here is another offering that uses only one loop to analyse the input. I made other changes which are commented.
#include <stdio.h>
int main(void)
{
int count[10] = { 0 };
int n;
int digit;
int elems = 0;
int diff = 0;
printf("Enter a whole number: ");
if(scanf("%d", &n) != 1 || n < 0) { // used %d, %i can accept octal input
puts("Please enter a positive number"); // always check result of scanf
return 1;
}
do {
elems++; // number of digits entered
digit = n % 10;
if(count[digit] == 0) { // number of different digits
diff++;
}
count[digit]++; // count occurrence of each
n /= 10;
} while(n); // do-while ensures a lone 0 works
printf("Number of digits entered: %d\n", elems);
printf("Number of different digits: %d\n", diff);
printf("Occurrence:\n");
for(n = 0; n < 10; n++) {
if(count[n]) {
printf(" %d of %d\n", count[n], n);
}
}
return 0;
}
Program session:
Enter a whole number: 82773712
Number of digits entered: 8
Number of different digits: 5
Occurrence:
1 of 1
2 of 2
1 of 3
3 of 7
1 of 8
so my task is as follows: Construct a do-while() loop, which continues to prompt the user for an integer, and determines the sum of integers entered, until a prime number is encountered. The prime number should not be included in the sum. Show all variable declarations.
I have all of the variable add up correctly however cannot seem to get the function to stop on a prime number. To try to correct this I made the variable "primecheck" and set it to 2++ thinking that it would be every integer above 2 (obviously not possible but one could hope). any assistance would be much appreciated!
int main (void)
{
int sum = 0, num = 0, i = 0, primecheck = 0, two = 2;
primecheck = two++;
do
{
printf ("Enter an integer: ");
scanf ("%d", &num);
if (num % primecheck == 0 && primecheck != num)
{
sum += num;
}
} while (num % primecheck == 0 && primecheck != num);
i = sum;
printf("%s%d%s", "Sum = ", i, "\n");
}
One possibility would be to introduce a function which performs the primality check, which could be done by using check divisions by all smaller numbers and terminate the loops as soon as a prime number is found. An implementation can be found following this link; the code can be refactored to the follwing function for primality testing. The function returns 1 if n is prime and 0 otherwise. The implementation uses an explicit while loop as the requirements apparently demands it.
int is_prime(int n)
{
int i=3;
int flag=0;
if (n%2==0)
{
return 0;
}
do
{
if (n%i==0)
{
flag=1;
break;
}
i+=2;
}
while (i*i<=n);
return flag;
}