为什么 scanf 在第一次循环后无法获取输入?

Why cannot scanf get input after the first loop?

我正在尝试将天气数据保存在结构中。在下面,当我使用 scanf 时,它在第一个循环中工作正常,但从第二个循环开始,scanf 被跳过,只执行 printf 语句。我怎样才能让 scanf 在整个循环中获取输入。这是我的代码:

#include <stdio.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>

struct weather
{
     char *date;
     int month;
     int day;
     int year;
     unsigned int h_temp;
     unsigned int l_temp;
     int max_wind_speed;
     int preciption;
     char notes [80];
};

void collect_data (struct weather *pinfo)
{
     int loop;
     char yes_no[2];

     time_t curtime; //declaring time variable

     //storing current system time in the time variable
     time(&curtime);

     //storing current time to time structure
     struct tm * wdate = localtime (&curtime);


     for (loop=0;loop<4;loop++)
     {
            if (loop!=0)
            {
                (pinfo+loop)->date = ctime(&curtime);
                (pinfo+loop)->day = wdate->tm_mday;
                (pinfo+loop)->month = wdate->tm_mon;
                (pinfo+loop)->year = wdate->tm_year;
            }
            /*else
            {
            recent_date(loop,wdate);
            }*/

          printf("\nEnter the high temperature of the day:");
          scanf("\n%d",&(pinfo+loop)->h_temp);
          printf("\nEnter the low temperature of the day:");
          scanf("\n%d",&(pinfo+loop)->l_temp);
          printf("\nEnter the maximum wind speed of the day:");
          scanf("\n%d",&(pinfo+loop)->max_wind_speed);
          printf("\nEnter the perciption of the day:");
          scanf("\n%d",&(pinfo+loop)->preciption);
          printf("\nDo you have any notes about the weather of the day (y/n):");
          scanf("\n%s",yes_no);

          if (strcmp(yes_no,"y")==0)
          {
                printf("\nNotes:\n");
                scanf("\n%[\n]s",(pinfo+loop)->notes);
          }
     }
}

int main ()
{
     struct weather info [4];

     collect_data(info);

     return 0;
}

格式错误。 scanf("\n%[\n]s"...


scanf() 由于 "\n"

首先丢弃 0 个或更多白色 space

然后由于 "%[\n]" 而扫描换行符。因为这时候输入的是't' from "today"。扫描失败并停止。

稍后 scanf("\n%d",&(pinfo+loop)->h_temp); 尝试将 't' 作为数字读入,但也失败了。然后事情变得更糟。

作为 评论,OP 可能想要 "\n%[^\n]"

主要 错误实际上是代码没有检查 scanf() 的结果来验证输入是否有效。

建议:

1) 使用" " 而不是"\n" 来跳过可选的white-space。两者的工作原理相同。 " " 是惯用语。

2) 使用宽度限制格式,例如 " %79[^\n]" for char notes [80];

3) 始终检查 scanf() 结果,如 if (1 !- scanf("\n%d",&(pinfo+loop)->h_temp) { puts("temp fail"); return -1; }

4) 考虑转储 scanf() 的所有用法并改用 fgets()


还有:

ctime() 重复使用同一个缓冲区。

return 值指向一个静态分配的字符串,该字符串可能会被后续调用任何日期和时间函数覆盖。

// (pinfo+loop)->date = ctime(&curtime);
// Make duplicate and remember to free when done.
(pinfo+loop)->date = strdup(ctime(&curtime));