来自stdin问题的fgets [C]

时间:2010-03-02 00:40:42

标签: c file file-io fgets

我正在编写一个可以处理文件的程序。 我需要能够将数据作为结构输入,并最终将其读出。 我目前遇到的问题是这段代码:

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...*/

如果我想要,例如,姓名地址和电话号码,并要求连续每一个(所以地址几乎与上面相同,除了用地址替换'名称'),我发现它跳过输入。我的意思是,我没有机会输入它。输出实际上是 输入名称: 输入地址:(这是它提示我输入的地方)

3 个答案:

答案 0 :(得分:3)

新行仍在stdin中,之前调用的函数没有从输入读取换行符。通过阅读清除stdin,直到您通过其他人建议的方式刷新stdin来读取换行符

编辑:谢谢Alok,为了更正!

答案 1 :(得分:2)

我尝试了您的代码,无法重现该问题。以下代码按照您期望的方式工作,它会提示输入名称,等待您输入名称,然后提示输入地址等。

我想知道你是否需要在提示更多输入之前读取标准输入并清空它?

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.或者,如果你想在你的记录中存储没有终止空值的名字,那么你需要使用memcpy将字符串复制到你的记录中,而不是的strcpy。

编辑:

我从评论中看到您正在使用scanf来读取选项值,这会在输入缓冲区中留下\ n,然后由您的第一个fgets调用选中。你应该做的是使用fgets读取选择行,然后使用sscanf来解析输入中的值。像这样

int choice;
char temp[50];
fgets(temp, sizeof(temp), stdin);
sscanf(temp, "%d", &choice);

这应该使整个问题冲洗stdin没有实际意义。

答案 2 :(得分:2)

在调用scanf读取名称之前,您可能使用choice来阅读fgetsscanf可能在stdin中留下了一个换行符,您的代码会因输入空名称而出错。如果确实如此,请尽量不要使用scanf(使用fgets检索choice并使用atoi转换为int或{{1}与“1 \ n”等进行比较。代码应以其他方式工作,并通过以下修改来解释strcmp还将终止换行符读入缓冲区(您可能希望将其删除)的事实:

fgets