如何忽略给定的控制台输入
How to ignore a given console input
我的问题(如标题所示)是如何忽略控制台中的输入。
我的程序将接受代表名字、中间名和姓氏的输入。例如,如果任何人没有中间名,stud.name.mdlename
应该为空,它应该被忽略,这样它就不会接受任何输入。
// write a program to read and display information of a
// student using a structure within a structure.
#include <stdio.h>
typedef struct studentName
{
char frstnme[10];
char mdlenme[10];
char lstnme[10];
}Name;
typedef struct studentdob
{
int dd;
int mm;
int yy;
}DOB;
typedef struct studentinfo
{
int r_no;
Name name;
char course[10];
DOB dob;
float fees;
};
int main()
{
struct studentinfo stud;
printf("\nEnter registration number : ");
scanf("%d",&stud.r_no);
printf("Enter First name :\n");
scanf("%s",stud.name.frstnme);
printf("Enter Middle name :\n");
scanf("%s",stud.name.mdlenme);
printf("Enter Last name :\n");
scanf("%s",stud.name.lstnme);
printf("\n");
printf("Enter DOB [dd.mm.yy]:");
scanf("%d %d %d",&stud.dob.dd,&stud.dob.mm,&stud.dob.yy);
printf("\nEnter the fees:");
scanf("%f",&stud.fees);
printf("\n ***Student's details***");
printf("\nRegistration number : %d",stud.r_no);
printf("\nName of student : %s %s %s",stud.name.frstnme,stud.name.mdlenme,stud.name.lstnme);
printf("\nD.O.B- %d.%d.%d",stud.dob.dd,stud.dob.mm,stud.dob.yy);
printf("\nTotal Fees :%f",stud.fees);
}
你的代码应该允许用户跳过输入,比方说,通过按回车键,让缓冲区留空,我的意思是只有 [=13=]
,你可以为此使用 fgets
,但是问题仍然存在,如果输入大于缓冲区的容量,stdin
上的剩余内容将保留在那里,影响未来的读数。
我建议使用更个性化的方法:
// 必需 headers:
#include <stdlib.h>
#include <assert.h>
// 辅助函数:
int clearbuffer() { // helper function to clear buffer
int c;
while ((c = getchar()) != '\n' && c != EOF){}
if (c == EOF) {
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
int readline(char *buffer, size_t size) { // custom line reading function
assert(size > 0 && size <= INT_MAX); // validate size parameter
size_t i = 0;
int ch;
// reads at most size of the buffer - 1, clearing the extra characters
while ((ch = fgetc(stdin)) != '\n' && ch != EOF) {
if(i < size - 1){
buffer[i++] = ch;
}
}
buffer[i] = '[=11=]';
return i;
}
// 主要代码:
int main(){
struct studentinfo stud;
size_t namesize = 0; //keep track of the student name length
printf("\nEnter registration number : ");
scanf("%d", &stud.r_no);
printf("Enter First name(Enter to skip): ");
if(clearbuffer() == EXIT_FAILURE){
fprintf(stderr, "Fatal error");
return EXIT_FAILURE;
}
namesize += readline(stud.name.frstnme, sizeof stud.name.frstnme);
printf("Enter Middle name(Enter to skip): ");
namesize += readline(stud.name.mdlenme, sizeof stud.name.mdlenme);
printf("Enter Last name name(Enter to skip): ");
namesize = readline(stud.name.lstnme, sizeof stud.name.lstnme);
printf("Enter DOB [dd.mm.yy]: ");
scanf("%d %d %d", &stud.dob.dd, &stud.dob.mm, &stud.dob.yy);
printf("\nEnter the fees: ");
scanf("%f", &stud.fees);
printf("\n ***Student's details***");
printf("\nRegistration number : %d", stud.r_no);
if(namesize > 0) // if all three names are empty, no need to print this
printf("\nName of student : %s %s %s", stud.name.frstnme, stud.name.mdlenme, stud.name.lstnme);
printf("\nD.O.B- %d.%d.%d", stud.dob.dd, stud.dob.mm, stud.dob.yy);
printf("\nTotal Fees :%f", stud.fees);
}
您仍然可以在代码中修复一些问题以使其更健壮,即输入值验证,这很难用 scanf
实现,我建议将输入读取为文本(使用fgets
或上面提供的自定义行 reader 函数)并使用 strtol
/ strtod
.
安全地转换值
或者,您应该记录代码在输入无效时的行为,无论是超出允许范围的值还是无效输入。
我还建议使用更精确的 double
类型,而不是 float
。
小问题,您在结构中使用 typedef
struct studentinfo
没有效果,您忘记给它命名。
我的问题(如标题所示)是如何忽略控制台中的输入。
我的程序将接受代表名字、中间名和姓氏的输入。例如,如果任何人没有中间名,stud.name.mdlename
应该为空,它应该被忽略,这样它就不会接受任何输入。
// write a program to read and display information of a
// student using a structure within a structure.
#include <stdio.h>
typedef struct studentName
{
char frstnme[10];
char mdlenme[10];
char lstnme[10];
}Name;
typedef struct studentdob
{
int dd;
int mm;
int yy;
}DOB;
typedef struct studentinfo
{
int r_no;
Name name;
char course[10];
DOB dob;
float fees;
};
int main()
{
struct studentinfo stud;
printf("\nEnter registration number : ");
scanf("%d",&stud.r_no);
printf("Enter First name :\n");
scanf("%s",stud.name.frstnme);
printf("Enter Middle name :\n");
scanf("%s",stud.name.mdlenme);
printf("Enter Last name :\n");
scanf("%s",stud.name.lstnme);
printf("\n");
printf("Enter DOB [dd.mm.yy]:");
scanf("%d %d %d",&stud.dob.dd,&stud.dob.mm,&stud.dob.yy);
printf("\nEnter the fees:");
scanf("%f",&stud.fees);
printf("\n ***Student's details***");
printf("\nRegistration number : %d",stud.r_no);
printf("\nName of student : %s %s %s",stud.name.frstnme,stud.name.mdlenme,stud.name.lstnme);
printf("\nD.O.B- %d.%d.%d",stud.dob.dd,stud.dob.mm,stud.dob.yy);
printf("\nTotal Fees :%f",stud.fees);
}
你的代码应该允许用户跳过输入,比方说,通过按回车键,让缓冲区留空,我的意思是只有 [=13=]
,你可以为此使用 fgets
,但是问题仍然存在,如果输入大于缓冲区的容量,stdin
上的剩余内容将保留在那里,影响未来的读数。
我建议使用更个性化的方法:
// 必需 headers:
#include <stdlib.h>
#include <assert.h>
// 辅助函数:
int clearbuffer() { // helper function to clear buffer
int c;
while ((c = getchar()) != '\n' && c != EOF){}
if (c == EOF) {
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
int readline(char *buffer, size_t size) { // custom line reading function
assert(size > 0 && size <= INT_MAX); // validate size parameter
size_t i = 0;
int ch;
// reads at most size of the buffer - 1, clearing the extra characters
while ((ch = fgetc(stdin)) != '\n' && ch != EOF) {
if(i < size - 1){
buffer[i++] = ch;
}
}
buffer[i] = '[=11=]';
return i;
}
// 主要代码:
int main(){
struct studentinfo stud;
size_t namesize = 0; //keep track of the student name length
printf("\nEnter registration number : ");
scanf("%d", &stud.r_no);
printf("Enter First name(Enter to skip): ");
if(clearbuffer() == EXIT_FAILURE){
fprintf(stderr, "Fatal error");
return EXIT_FAILURE;
}
namesize += readline(stud.name.frstnme, sizeof stud.name.frstnme);
printf("Enter Middle name(Enter to skip): ");
namesize += readline(stud.name.mdlenme, sizeof stud.name.mdlenme);
printf("Enter Last name name(Enter to skip): ");
namesize = readline(stud.name.lstnme, sizeof stud.name.lstnme);
printf("Enter DOB [dd.mm.yy]: ");
scanf("%d %d %d", &stud.dob.dd, &stud.dob.mm, &stud.dob.yy);
printf("\nEnter the fees: ");
scanf("%f", &stud.fees);
printf("\n ***Student's details***");
printf("\nRegistration number : %d", stud.r_no);
if(namesize > 0) // if all three names are empty, no need to print this
printf("\nName of student : %s %s %s", stud.name.frstnme, stud.name.mdlenme, stud.name.lstnme);
printf("\nD.O.B- %d.%d.%d", stud.dob.dd, stud.dob.mm, stud.dob.yy);
printf("\nTotal Fees :%f", stud.fees);
}
您仍然可以在代码中修复一些问题以使其更健壮,即输入值验证,这很难用 scanf
实现,我建议将输入读取为文本(使用fgets
或上面提供的自定义行 reader 函数)并使用 strtol
/ strtod
.
或者,您应该记录代码在输入无效时的行为,无论是超出允许范围的值还是无效输入。
我还建议使用更精确的 double
类型,而不是 float
。
小问题,您在结构中使用 typedef
struct studentinfo
没有效果,您忘记给它命名。