2

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

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

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

4

3 回答 3

3

换行符仍然stdin来自先前调用未从输入中读取换行符的函数。stdin通过阅读直到您读出换行符来清除-而不是stdin像其他人建议的那样通过冲洗。

编辑:谢谢阿洛克,更正!

于 2010-03-02T01:04:48.990 回答
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);

   ...    
}

顺便说一句,您想将 1 加到 strlen(name),而不是减 1。或者,如果您希望 name 存储在您的记录中而没有终止 null,那么您需要使用 memcpy 将字符串复制到您的记录中,而不是 strcpy。

编辑:

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

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

这应该会使刷新标准输入的整个问题变得毫无意义。

于 2010-03-02T00:57:38.863 回答
2

您可能习惯在打电话之前scanf阅读姓名。 可能留下了一个换行符,您的代码在其中错误地输入了空名称。如果确实如此,请尽量不要使用(用于检索和用于转换或比较“1\n”等)。否则代码应该可以工作,并进行以下修改以说明还将终止换行符读入缓冲区(您可能希望将其剥离)的事实:choicefgetsscanfstdinscanffgetschoiceatoiintstrcmpfgets

  #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);
于 2010-03-02T01:09:55.203 回答