[英]fgets from stdin problems [C]
我正在编写一个处理文件的程序。 我需要能够将数据作为结构输入,并最终将其读出。 我目前的问题是与此代码:
typedef struct {
char* name;
.....
}employeeRecord;
employeeRecord record;
char name[50];
if(choice == 1)
{
/*Name*/
printf("\nEnter the name:");
fgets(name,50,stdin);
record.nameLength = strlen(name) -1;
record.name = malloc(sizeof(char)*record.nameLength);
strcpy(record.name,name);
/*Other data, similar format...*/
例如,如果我想要命名地址和电话号码,并连续要求输入(因此地址与上述地址几乎相同,只不过用地址替换“名称”),我发现它会跳过输入。 我的意思是,我没有机会输入它。 输出实际上是输入名称:输入地址:(这是提示我输入的位置)
从先前调用未从输入中读取换行符的函数之前,换行符仍处于stdin
输入中。 通过阅读来清除stdin
,直到您读出换行符为止- 而不是像其他人建议的那样冲洗stdin
。
编辑:感谢Alok,为更正!
我尝试了您的代码,无法重现该问题。 以下代码按您期望的方式工作,它提示输入名称,等待您键入名称,然后提示输入地址,等等。
我想知道您是否在提示输入更多信息之前不需要阅读stdin并将其清空?
typedef struct {
char* name;
char* address;
}employeeRecord;
int readrecord(employeeRecord &record)
{
char name[50];
char address[100];
printf("\nenter the name:");
fgets(name, sizeof(name), stdin);
record.nameLength = strlen(name) + 1;
record.name = malloc(sizeof(char)*record.nameLength);
strcpy(record.name,name);
printf("\nenter the address:");
fgets(address, sizeof(address), stdin);
...
}
顺便说一句,您想在strlen(name)上加1,而不是减1。或者,如果要将名称存储在记录中而没有终止null,则需要使用memcpy将字符串复制到您的记录中,而不是strcpy。
我从注释中看到,您正在使用scanf
读取选择值,这在输入缓冲区中留下一个\\ n,然后由您的第一个fgets
调用将其拾取。 相反,您应该使用fgets在选择行中进行读取,然后使用sscanf从输入中解析出值。 像这样
int choice;
char temp[50];
fgets(temp, sizeof(temp), stdin);
sscanf(temp, "%d", &choice);
这应该使整个冲洗stdin问题变得毫无意义。
您可能在调用fgets
读取名称之前使用scanf
来读取choice
。 scanf
可能在stdin
留下了换行符,您的代码错误输入了一个空名称。 如果确实如此,请尝试不要使用scanf
(使用fgets
检索choice
并使用atoi
转换为int
或strcmp
以与“ 1 \\ n”进行比较,等等)。 该代码应该可以正常工作,并进行以下修改以考虑以下事实: fgets
还将终止换行符读入缓冲区(您可能希望剥离):
#define MY_LENOF(x) (sizeof(x)/sizeof((x)[0]))
char choice[3] = { 0 }; /* example of how to initialize to all NULs */
if (!fgets(choice, MY_LENOF(choice), stdin)) {
fprintf(stderr, "Premature end of input\n");
exit(1);
}
if (strcmp(choice, "1\n") == 0) {
/*Name*/
printf("\nEnter the name:");
if (!fgets(name, MY_LENOF(name), stdin)) {
/* if fgets fails it leaves name unchanged, so we reset it to "" */
name[0] = '\0';
}
/* good practice to use srtnlen in order not to overrun fixed buffer */
/* not necessarily a problem with fgets which guarantees the trailing NUL */
size_t nameLength = strnlen(name, MY_LENOF(name));
assert(name[nameLength] == '\0');
if (nameLength - 1 > 0 && name[nameLength - 1] == '\n') {
/* strip trailing newline */
name[--nameLength] = '\0';
} else if (nameLength >= MY_LENOF(name) - 1) {
fprintf(stderr, "Name is too long\n");
exit(1);
} else {
fprintf(stderr, "Premature end of input\n");
exit(1);
}
record.nameLength = nameLength;
record.name = malloc(sizeof(char)*(record.nameLength + 1));
strcpy(record.name, name);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.