获取字符串后,在单个scanf中取字符串和整数会跳过其余的整数,为什么?如何在单扫描中完成?

问题描述 投票:0回答:1

我需要从单个scanf获取整数和字符串。但是,除非我使用两个scanfs,否则代码不会使用剩余的整数。如何获得这个单一的scanf函数来获取我输入的所有内容?

struct student {
    int r;
    char a[50];
    int c1, c2, c3;
    float total, per;
} s[100];

main() {
    int i, n;
    printf("Enter total number of students\n");
    scanf("%d", &n);
    for (i = 0; i < n; i++) {
        printf("Enter details of student\nRollNo Name c1 c1 c3 marks\n");
        scanf("%d %[^\n]*%s %d %d %d", &s[i].r, s[i].a, &s[i].c1, &s[i].c2, &s[i].c3);
       // scanf("%d %d %d", &s[i].c1, &s[i].c2, &s[i].c3);  this works 
    }
    for (i = 0; i < n; i++) {
        printf("%d %s %d %d %d\n", s[i].r, s[i].a, s[i].c1, s[i].c2, s[i].c3);
    }
}
c scanf
1个回答
1
投票

读取与换行符不同的字符串的格式是%[^\n],带有可选但强烈推荐的宽度前缀,用于存储到目标数组中的最大字符数。落后的*%s毫无意义。但请注意,此scanf转换说明符将接受标记号作为名称的一部分:

scanf应该在找到一个数字时停止读取该名称。这将允许用户在每个学生的单行上给出输入,他/她可能会根据提示进行操作。

其格式为%[^0-9\n],如果用户输入的名称超过49个字符,则要防止未定义的行为,请使用%49[^0-9\n]指定此限制。

使用scanf()解析输入仍然很脆弱:从无效输入中恢复是乏味的。

这是一个更正版本:

#include <stdio.h>

struct student {
    int r;
    char a[50];
    int c1, c2, c3;
    float total, per;
} s[100];

int main() {
    int i, n;

    printf("Enter total number of students\n");
    if (scanf("%d", &n) != 1 || n > 100)
        return 1;

    for (i = 0; i < n;) {
        printf("Enter details of student\nRollNo Name c1 c1 c3 marks\n");
        if (scanf("%d %49[^0-9\n] %d %d %d",
                  &s[i].r, s[i].a, &s[i].c1, &s[i].c2, &s[i].c3) == 5) {
            i++;
        } else {
            int c;
            fprintf(stderr, "input error\n");
            /* consume the rest of the input line */
            while ((c = getchar()) != EOF && c != '\n')
                continue;
            if (c == EOF) {
                fprintf(stderr, "unexpected end of file\n");
                return 1;
            }
        }
    }
    for (i = 0; i < n; i++) {
        printf("%d %s %d %d %d\n", s[i].r, s[i].a, s[i].c1, s[i].c2, s[i].c3);
    }
    return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.