-3

I want the input number to be stored somewhere so I can their total later, can someone help?

#include<stdio.h>
#include<conio.h>

main() {
    int range;
    int num;
    int i;
    int total = 0;

    printf("how many numbers will you put?\n");
    scanf("%d", &range);

    for(i=0;i<range;i++) {
        printf("please enter the number\n");
        scanf("%d", &num); 
    }
    printf("%d", total);

    return 0;
}
Andy J
  • 1,479
  • 6
  • 23
  • 40
  • 1
    You just need to calculate the total right, why not do it during the time of input – zenwraight Aug 30 '18 at 07:24
  • 1
    You can try to calculate the total while processing the input – Zendy Aug 30 '18 at 07:25
  • Note: aside from new C users who fail to **check the return** of `scanf` being traditionally shot at sunrise -- you will also benefit from avoiding *Undefined Behavior* in the mean time... E.g. simply `if (scanf ("%d", &num) == 1) total += num;`, then you already have total when you leave the loop `:)` (you should also add an `else` condition there to handle any error (like a stray character being typed) **and** remove the extraneous characters that remain unread in `stdin` to prevent your code from that point on working like "Groundhog Day"...) – David C. Rankin Aug 30 '18 at 07:26
  • You can use an [array](https://www.google.com/search?q=c+array), but as zenwraight and Zendy just said you'd better calculate your sum on-the-fly – joH1 Aug 30 '18 at 07:27
  • Just add: `for(i=0;i – devd Aug 30 '18 at 07:32
  • Use arrays, and based on indexes you can access and add them later when needed. – Rizwan Aug 30 '18 at 07:32

3 Answers3

1

In addition to the other advice you have received, you still must handle removing any character that causes scanf to fail. Why? When a matching or input failure occurs with scanf, all reading from stdin stops and no more characters are read (leaving the character that caused the problem just waiting to bite you again on your next call to scanf.

To remedy the problem, you are responsible for accounting for any characters that remain (which you can only determine by checking the return from scanf. If a matching or input failure occurs, then you can use a simple help function to read and discard all characters up to your next '\n' or EOF whichever occurs first, e.g.

void empty_stdin (void)
{
    int c = getchar();

    while (c != '\n' && c != EOF)
        c = getchar();
}

Then simply incorporate that within your code any time you experience a matching or input failure (and when passing control to another area that will take input -- just to make sure the input buffer is clean.

Putting those pieces together, you can do something similar to the following:

#include <stdio.h>
// #include <conio.h>  /* don't use conio.h -- it is DOS only */

void empty_stdin (void)
{
    int c = getchar();

    while (c != '\n' && c != EOF)
        c = getchar();
}

int main (void) {
    int range,
        num,
        i,
        total = 0;

    printf ("how many numbers will you enter: ");
    if (scanf ("%d", &range) != 1) {
        fputs ("error: invalid input - range.\n", stderr);
        return 1;
    }

    for (i = 0; i < range; i++) {
        for (;;) {  /* loop continually until you get the input you need */
            int rtn;
            printf ("\n  enter number[%2d]: ", i + 1);
            rtn = scanf("%d", &num);
            if (rtn == EOF) {   /* handle user EOF */
                fputs ("user canceled input.\n", stderr);
                return 1;
            }
            else if (rtn == 0) {    /* handle matching or input failure */
                fprintf (stderr, "error: invalid input, number[%d]\n", i + 1);
                empty_stdin ();
            }
            else        /* good conversion, break read loop */
                break;
        }
        total += num;   /* add num to total */
    }
    printf ("\nTotal: %d\n", total);

    return 0;
}

Example Use/Output

With an intentional matching failure induced in the input:

$ ./bin/scanftotal
how many numbers will you enter: 4

  enter number[ 1]: 10

  enter number[ 2]: 20

  enter number[ 3]: foo
error: invalid input, number[3]

  enter number[ 3]: 30

  enter number[ 4]: 40

Total: 100

Look things over and let me know if you have further questions. (and avoid the fate noted in my comment to your question...)

Toby Speight
  • 27,591
  • 48
  • 66
  • 103
David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
  • Could you just `scanf("%*[^\n] ");` as a simpler form of `empty_stdin()`? – Toby Speight Aug 30 '18 at 08:26
  • Well, you could, but you would have to have a sufficient sized buffer to hold all possible unwanted characters that may be in the input buffer. (that can be quite a few thousand if a cat steps on the keyboard). Using `getchar()` eliminates all buffer constraints. But sure, it could work. – David C. Rankin Aug 30 '18 at 08:30
  • The `*` in the conversion specifier suppresses assignment, so no buffer is required. (Yes, I did compile and run!) – Toby Speight Aug 30 '18 at 08:31
  • Er, right -- late here, tired eyes. With the assignment suppression operator it would work, but then you look at the differences in efficiency between calling a *variadic* input function, or simply calling a character function (which ultimately is what `scanf` will do behind the scenes). The IO buffer on Linux loads 8192 chars at a time into the input buffer, using `getchar` simply iterates over characters in memory, so it is lightning quick (Windows provides a 500 char buffer for the same purpose) You can check by outputting the `BUFSIZ` constant. – David C. Rankin Aug 30 '18 at 08:37
0

You were quite close with your attempt. As David C. Rankin mentioned all you were really doing wrong is just not checking the return value of scanf().

#include <stdio.h>

int main(int argc, char **argv)
{
    int range, num, i;
    int total = 0;
    int scanf_result = 0;

    setbuf(stdout, NULL);

    printf("How many numbers will you enter?\n");
    scanf_result = scanf("%d", &range);
    if((scanf_result != 1) || (range < 1))
    {
        printf("Invalid number");
        return 1;
    }

    for(i=0; i<range; i++) {
        printf("Please enter a number: \n");
        scanf_result = scanf("%d", &num);
        if(scanf_result != 1)
        {
            printf("Invalid number");
            return 1;
        } else
        {
            total = total + num;
        }
    }
    printf("Total is: %d", total);

    return 0;
}
Andy J
  • 1,479
  • 6
  • 23
  • 40
-1

Other commenters are right that in in the general case, you should probably just compute the sum while reading numbers. Follows other answers advices like clearing standard input, and maybe offer a way for the user to retry an input in case of error.

But also, be careful about undefined behaviours. For example, computing the sum with signed integers might lead to undefined behavior close to INT_MAX and INT_MIN. You should probably check before doing the sum that the distance towards those bounds is lower than the current number being added (by the way, see also Detecting integral overflow with scanf)

Or, you could put your numbers into an array and benefits from the fact that integer addition is commutative to cancel overflows when possible. Here is a possible approach (tested, but there might still be errors):

#include <stdio.h>
#include <limits.h>

/* arbitrary limit */
#define MAX_RANGE 32

/* numbers being read */
int numbers[MAX_RANGE];

/* non-zero if number was already added in sum */
int added[MAX_RANGE];

int main()
{
    int scan;
    int range;
    int num;
    int i;
    int sum;
    int overflow;
    int changed;

    printf("INT_MAX is %d\n", INT_MAX);
    printf("How many numbers will you put? (0-%d): ", MAX_RANGE-1);
    fflush(stdout);
    scan = scanf("%d", &range);
    if (scan != 1) {
        perror("Cannot read range: ");
        return -1;
    }

    if (!(0 <= range && range <= MAX_RANGE)) {
        fprintf(stderr, "Out of range");
        return -1;
    }

    for(i = 0; i < range; i++) {
        printf("Please enter a number\n");
        scan = scanf("%d", &num);
        if (scan != 1) {
            perror("Error when reading number: ");
            return -1;
        }
        numbers[i] = num;
        added[i] = 0;
    }

    sum = 0;
    do {
        changed = 0;
        overflow = 0;
        printf("loop: %d\n", sum);
        for (i = 0; i < range; i++) {
            if (added[i]) { 
                continue;
            }
            num = numbers[i];
            if (sum > 0) {
                if (num > (INT_MAX - sum)){
                    overflow = 1;
                    continue;
                }
            } else {
                if (num < (INT_MIN - sum)) {
                    overflow = 1;
                    continue;
                }
            }
            printf("adding %d\n", num);
            added[i] = 1;
            changed = 1;
            sum += num;
        }
    } while (overflow && changed);

    if (overflow) {
        fprintf(stderr, "Overflow\n");
        return -2;
    }

    printf("Total: %d\n", sum);
    return 0;
}

The for loop tries to sum all numbers but skips over those that lead to an overflow. The do...while loop tries the for loop until we find a sum or the overflow is unavoidable. For example:

INT_MAX is 2147483647
How many numbers will you put? (0-31): 5
Please enter a number
2147483647
Please enter a number
2147483647
Please enter a number
-2147483647
Please enter a number
-2147483647
Please enter a number
0
loop: 0
adding 2147483647
adding -2147483647
adding -2147483647
adding 0
loop: -2147483647
adding 2147483647
Total: 0
coredump
  • 37,664
  • 5
  • 43
  • 77