我希望输入数字存储在某个地方,以便以后可以总计,有人可以帮忙吗?
#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;
}
答案 0 :(得分:1)
除了您收到的其他建议之外,您还必须删除所有导致scanf
失败的字符。为什么?当scanf
发生 matching 或 input 失败时,从stdin
进行的所有读取都将停止,并且不再读取任何字符(导致问题只是在您下次致电scanf
时再次咬你。
要解决此问题,您需要对剩余的所有字符负责(您只能通过检查从scanf
返回的字符来确定。如果匹配或 input 发生故障,那么您可以使用简单的帮助功能来读取和丢弃直到下一个'\n'
或EOF
为止的所有字符,例如先出现的< >
void empty_stdin (void)
{
int c = getchar();
while (c != '\n' && c != EOF)
c = getchar();
}
然后,只要您遇到匹配或输入失败(以及将控制权传递到将接受输入的另一个区域时,只要确保输入缓冲区是干净的),就可以将其简单地合并到代码中。
将这些片段放在一起,您可以执行以下操作:
#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;
}
使用/输出示例
在输入中引发了有意匹配失败:
$ ./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
仔细检查一下,如果还有其他问题,请告诉我。 (并避免我在对您的问题的评论中指出的命运...)
答案 1 :(得分:0)
您的尝试非常接近。正如David C. Rankin提到的,您真正做错的只是不检查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;
}
答案 2 :(得分:-1)
其他评论者是正确的,在一般情况下,您可能应该只在读取数字时计算总和。遵循其他答案的建议,例如清除标准输入,并可能为用户提供一种在出现错误的情况下重试输入的方法。
但也要注意不确定的行为。例如,使用有符号整数计算和可能会导致未定义行为接近INT_MAX
和INT_MIN
。您可能应该在做总和之前检查到这些边界的距离是否小于当前添加的数字
(顺便请参见Detecting integral overflow with scanf)
或者,您可以将数字放入数组,并受益于整数加法可交换以在可能时消除溢出的事实。这是一种可能的方法(经过测试,但可能仍然存在错误):
#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;
}
for
循环尝试对所有数字求和,但跳过那些导致溢出的数字。 do...while
循环将尝试for
循环,直到找到一个总和或溢出是不可避免的。例如:
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