简体   繁体   English

Scanf需要比C中更多的值

[英]Scanf needs more values than it should in C

I'm trying to learn structs and I'm using this code 我正在尝试学习结构,并且正在使用此代码

#include <stdio.h>

struct elements
{
    char name[50];
    int semester;
    char  am[15];
}student[100];

void read_struct(struct elements p[]);
int i=0;

main()
{

    for (i=0;i<2;i++)
    {
        read_struct(student);

    }
    for (i=0;i<2;i++)
    {   printf("%d\n",i);
        printf("%s\n",student[i].name);
        printf("%s\n",student[i].am);
        printf("%d\n",student[i].semester);
    }

    system("pause");
}
void read_struct(struct elements p[])
{

    gets(student[i].name);
    gets(student[i].am);
    scanf("%d\n",&student[i].semester);
}

and I face the following problem: during the second iteration when I enter the value for the variable student[1].semester the program doesn't print what I've entered but it waits for me to enter another number,press enter and then it prints. 并且我遇到了以下问题:在第二次迭代中,当我输入变量student[1].semester ,程序不会打印我输入的内容,但会等待我输入另一个数字,按Enter键,然后它打印。 I tried fflush(stdin) after every gets and scanf, and I got the same problem. 我在每次获取和scanf之后都尝试了fflush(stdin) ,但遇到了同样的问题。

Try replacing 尝试更换

scanf("%d\n", &student[i].semester);

with

scanf("%d", &student[i].semester);

In addition to that, fflush(stdin) invokes undefined behaviour, so don't use it. 除此之外, fflush(stdin)调用未定义的行为,因此不要使用它。

Your code is wrong on so many levels. 您的代码在许多级别上都是错误的。 Instead of just adding a comment pointing them out I will show you a "more correct" way: 我将为您展示一种“更正确”的方式,而不仅仅是添加注释以指出它们:

#include <stdio.h>
#include <string.h>

struct elements
{
    char name[50];
    int semester;
    char  am[15];
};

#define MAX_STUDENTS 2

void read_struct(struct elements *p);

int main(void)
{
    struct elements students[MAX_STUDENTS];  /* No longer global */

    for (size_t i = 0;i < MAX_STUDENTS; ++i)
        read_struct(&students[i]);  /* Pass pointer to single structure */

    for (size_t i = 0;i < MAX_STUDENTS; ++i)
    {
        printf("%ld\n", i);
        printf("%s\n", students[i].name);
        printf("%s\n", students[i].am);
        printf("%d\n", students[i].semester);
    }
}

void read_struct(struct elements *p)
{
    /* fgets is safe, in that it will not overwrite your buffer */
    fgets(p->name, sizeof(p->name), stdin);
    fgets(p->am, sizeof(p->am), stdin);
    scanf("%d", &p->semester);

    /* Skip trailing whitespace (like the newline) in the input buffer
     * left after the `scanf` call above.
     * Do it by reading one character and see if it's a newline. If it's
     * not a newline, then read next character, and so on until we get
     * the newline. It's safe because we *know* there is a newline in the
     * input buffer after the `scanf` call above.
     */
    int c;
    while ((c = fgetc(stdin)) != EOF && c != '\n')
        ;

    /* The `fgets function leaves the newline in the buffer so we
     * have to remove it, if it's there.
     * This is done by first checking if the last character (strlen(...) - 1)
     * is a newline, and if it is then we change that newline to the string
     * terminator character so the string is terminated there.
     */
    if (p->name[strlen(p->name) - 1] == '\n')
        p->name[strlen(p->name) - 1] = '\0';
    if (p->am[strlen(p->am) - 1] == '\n')
        p->am[strlen(p->am) - 1] = '\0';
}

The reason the trailing whitespace doesn't really work is because then the scanf function will continue to read input until it sees something non-whitespace. 尾随空格不能真正起作用的原因是因为scanf函数将继续读取输入,直到看到非空格为止。 In this case after you entered the last data, the scanf still wants to read and discard all whitespace, it doesn't know that the user isn't supposed to enter any more input. 在这种情况下,输入最后一个数据后, scanf仍要读取并丢弃所有空白,它不知道用户不应该再输入任何内容。

You really have to manually read and skip trailing whitespace as done in my program above. 您确实必须像上面我的程序一样手动读取和跳过结尾的空格。

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

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