简体   繁体   English

n个数的和

[英]Sum of n numbers

#include <stdio.h>

int main()
{   
    int m,i,sum,num;

    i=0;
    sum=0;
    scanf("%d ",&m);
    while(i<m){
        scanf("%d ",&num);

        sum=sum + num;

        i=i+1;
        printf("Value of sum= %d\n",sum);
        //continue;
    }
    printf("Sum= %d ",sum);
}

In the above code it should display the sum of n numbers. 在上面的代码中,它应该显示n个数字的总和。 But in my code it is taking one extra value of m (m is number of values to take to compute the sum). 但是在我的代码中,它需要一个额外的m值(m是计算总和所需的值的数量)。

For example if I take m as 3 it takes 4 input and displays the sum of 3. 例如,如果我将m取为3则需要4个输入并显示3的总和。

As others(@BLUEPIXY and @BillDoomProg) have already pointed in the comments, your problem is the space in your scanf format string. 正如其他人(@ BLUEPIXY和@BillDoomProg)已经在评论中指出的那样,你的问题是你的scanf格式字符串中的空格。 Also check this answer . 还要检查这个答案

Change both your scanf format string from: 从以下位置更改scanf格式字符串:

scanf("%d ",&m);
...
scanf("%d ",&num);

To: 至:

scanf("%d", &m);
...
scanf("%d", &num);

Just remove the space and it will work fine. 只需删除空间,它将正常工作。

scanf() scanf()函数

From the manual 从手册

The format string consists of a sequence of directives(...) 格式字符串由一系列指令组成(...)

A directive is one of the following: 指令是以下之一:

A sequence of white-space characters (space, tab, newline, etc.; see isspace(3)). 一系列空格字符(空格,制表符,换行符等;请参阅isspace(3))。 This directive matches any amount of white space, including none, in the input. 该指令在输入中匹配任意数量的空白,包括无空格。

Also note that stdin is buffered, so the results are a little different from what you would expect: 另请注意, stdin是缓冲的,因此结果与您的预期略有不同:

man stdin

Notes 笔记

The stream stderr is unbuffered. stderr是无缓冲的。 The stream stdout is line-buffered when it points to a terminal. 当流stdout指向终端时,它是行缓冲的。 Partial lines will not appear until fflush(3) or exit(3) is called, or a newline is printed. 在调用fflush(3)或exit(3)或打印换行符之前,不会出现部分行。 This can produce unexpected results, especially with debugging output. 这可能会产生意外结果,尤其是调试输出时。 The buffering mode of the standard streams (or any other stream) can be changed using the setbuf(3) or setvbuf(3) call. 可以使用setbuf(3)或setvbuf(3)调用来更改标准流(或任何其他流)的缓冲模式。 Note that in case stdin is associated with a terminal, there may also be input buffering in the terminal driver, entirely unrelated to stdio buffering . 注意,在stdin与终端相关联的情况下,终端驱动程序中也可能存在输入缓冲,与stdio缓冲完全无关 (Indeed, normally terminal input is line buffered in the kernel.) This kernel input handling can be modified using calls like tcsetattr(3); (实际上,通常终端输入在内核中是行缓冲的。)这个内核输入处理可以使用像tcsetattr(3)这样的调用来修改。 see also stty(1), and termios(3). 另见stty(1)和termios(3)。

So, lets examine your program step by step. 所以,让我们一步一步地检查你的程序。

Your program starts running and you enter the number 2. This is what the input buffer looks like: 您的程序开始运行并输入数字2.这是输入缓冲区的样子:

2\n

scanf("%d ", &m) assigns 2 to the m variable and starts trying to match a space. scanf("%d ", &m)m变量赋值2并开始尝试匹配空格。 It gets a NL and EOL . 它获得了NLEOL Control is still with this scanf because it just matched a newline (considered a white-space) and is waiting to match more, but instead it got the End-Of-Line , so it is still waiting when you type: 控制仍然使用此scanf因为它只是匹配换行符(被认为是空格)并且正等待匹配更多,但它得到了行End-Of-Line ,所以当你输入时它仍在等待:

1\n

Then reads stdin again and realizes that the next character in the input stream is not a space and returns (it's format string condition was done). 然后再次读取stdin并意识到输入流中的下一个字符不是空格并返回(它的格式字符串条件已完成)。 At this point, you enter the loop and your next scanf("%d ",&num) is called and it wants to read an integer, which it does : it reads 1 and stores that in the num variable. 此时,您进入循环并调用下一个scanf("%d ",&num)并且它想要读取一个整数, 它执行 :它读取1并将其存储在num变量中。 Then again it starts matching white-spaces and gets the new-line and it repeats the above pattern. 然后它再次开始匹配空格并获得新线并重复上述模式。 Then when you enter: 然后当你输入:

2\n

That second scanf gets a character different than a white-space and returns, so your loop scope keeps executing printing the current sum . 第二个scanf获得的字符与白色空格不同并返回,因此您的循环范围将继续执行打印当前sum The loop break condition is not met, so it starts again. 不满足循环中断条件,因此它再次启动。 It calls the scanf and it effectively reads an integer into the variable, then the pattern repeats itself... 它调用scanf并且它有效地将整数读入变量,然后模式重复自身......

3\n

It was waiting for a white-space but it got a character instead. 它正在等待一个白色空间,但却有一个角色。 So your scanf returns and now the loop break condition is met . 所以你的scanf返回,现在满足循环中断条件 This is where you exit your loop, prints the whole sum and get that weired felling that it "added" 3 numbers but the sum is adding only the first 2 (as you intended in the first place). 这是你退出循环的地方,打印整个sum并得到那个“添加”3个数字但是总和仅添加前2个 (如你在第一个地方所预期的那样)。

You can check that 3 hanging in stdin with a simple addition to your code: 您可以通过简单添加代码来检查3在stdin中挂起:

#include <stdio.h> 

int main()
{

    int m, i, sum, num;
    char c;

    i = 0;
    sum = 0;
    scanf("%d ", &m);

    while (i < m) {
        scanf("%d ", &num);

        sum = sum + num;

        i = i + 1;
        printf("Value of sum= %d\n", sum);
    }

    while((c = getchar()) != '\n') 
        printf("Still in buffer: %c", c);

    return 0;
}

That will output (with the above input, of couse): 这将输出(使用上面的输入,couse):

$ ./sum1
2
1
2
Value of sum= 1
3
Value of sum= 3
Still in buffer: 3

This is because you have a space after your %d in the scanf lines. 这是因为你在scanf行中的%d之后有一个空格。

Change 更改

scanf("%d ",&num);

To

scanf("%d",&num);   

Scanf usually ignores whitespaces, so you don't want spaces in your format strings. Scanf通常会忽略空格,因此您不希望格式字符串中包含空格。

It's causes of extra space in scanf() . 这是extra space in scanf()extra space in scanf()的原因。 Change scanf("%d ",&num) to scanf("%d",&num) scanf("%d ",&num) to scanf("%d",&num)

From Scanf(), fscanf() , You can follow this. Scanf(),fscanf() ,你可以按照这个。

The scanf() family of functions reads data from the console or from a FILE stream, parses it, and stores the results away in variables you provide in the argument list. scanf()系列函数从控制台或FILE流中读取数据,对其进行解析,并将结果存储在您在参数列表中提供的变量中。

The format string is very similar to that in printf() in that you can tell it to read a "%d", for instance for an int. 格式字符串与printf()中的格式字符串非常相似,因为您可以告诉它读取“%d”,例如对于int。 But it also has additional capabilities, most notably that it can eat up other characters in the input that you specify in the format string. 但它还有其他功能,最值得注意的是它可以占用您在格式字符串中指定的输入中的其他字符。

You should write: 你应该写:

int main()
{
    int m,i,sum,num;

    i=0;
    sum=0;
    scanf("%d",&m);
    while(i<m){
        scanf("%d",&num);

        sum=sum + num;

        i=i+1;
        printf("Value of sum= %d\n",sum);
        //continue;
    }
    printf("Sum= %d ",sum);
}

A refactored code will look like this 重构的代码将如下所示

#include <stdio.h>

int main() {
    int m, num, sum = 0;
    scanf("%d", &m);    // Let scanf automatically skip whitespace
    while (m--) {
        scanf("%d", &num);
        sum += num;
    }
    printf("Sum= %d\n", sum);
    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM