获取字符串后,在单个scanf中取字符串和整数会跳过其余的整数,为什么?如何在单扫描中完成?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了获取字符串后,在单个scanf中取字符串和整数会跳过其余的整数,为什么?如何在单扫描中完成?相关的知识,希望对你有一定的参考价值。
我需要从单个scanf
获取整数和字符串。但是,除非我使用两个scanf
s,否则代码不会使用剩余的整数。如何获得这个单一的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中取字符串和整数会跳过其余的整数,为什么?如何在单扫描中完成?的主要内容,如果未能解决你的问题,请参考以下文章