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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了获取字符串后,在单个scanf中取字符串和整数会跳过其余的整数,为什么?如何在单扫描中完成?相关的知识,希望对你有一定的参考价值。

我需要从单个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);
    }
}
答案

读取与换行符不同的字符串的格式是%[^\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;
}

以上是关于获取字符串后,在单个scanf中取字符串和整数会跳过其余的整数,为什么?如何在单扫描中完成?的主要内容,如果未能解决你的问题,请参考以下文章

scanf

C语言中printf输出float和double都用%f么(scanf又如何)

C语言输入字符和字符串

scanf函数读入整数后接着读字符串的换行符残余问题

Scanf--数据第一个字符是西文字符的scanf函数

c语言(用最简单的,初学)从键盘输入四个整数,求平均值.数据输入,计算结果和输出要求有注释