Scanf while loop и обработка EOF - PullRequest
       37

Scanf while loop и обработка EOF

1 голос
/ 02 апреля 2011

У меня есть текстовый файл, который мы должны обработать, в формате

дд - день мм - месяц гггг - год x, y, w, z - температуры

дд, мм, гггг, х, у, г, ш * 1 005 *

1,1,2010,20.8,19.2,29.3,20.9
2,1,2010,22.5,15.5,30.7,23.3
3,1,2010,21.4,14.5,21.5,18.9
4,1,2010,27.6,13.4,23.9,18.2
5,1,2010,25,16,26.1,18.3
6,1,2010,23.6,16.1,27.6,21.8
...
29,1,2010,23.5,17.5,30.2,19.6
30,1,2010,36.2,13.4,27.3,20.5
31,1,2010,37.2,17.1,26.6,21.5
1,2,2010,24.9,16.9,27.7,22.6
2,2,2010,35.2,16.7,27.7,22.7
3,2,2010,34.8,21.6,27.3,21.4
...
1,12,2010,26.6,16.5,20.1,17.2
2,12,2010,27.2,17.2,24.3,18.5
3,12,2010,30,17.2,24.4,19.8
...
30,12,2010,23.7,14.2,26.5,20
31,12,2010,41.1,14.9,27.2,21.4

Нас не учили использовать массивы для обработки этих данных, только функции, операторы if / else, циклы (while / for) и операции.

Мне нужно обрабатывать данные за каждый месяц отдельно. Мой основной код содержится в цикле while (scanf("%d,%d,%d,%f,%f,%f,%f", &dd, &mm, &yyyy, &x, &y, &z, &w) ==7) {}.

Ниже мой код:

while (scanf("%d,%d,%d,%f,%f,%f,%f", &dd, &mm, &yyyy, &melmax, &melmin, &sydmax, &sydmin) ==7) {
        if (totallinesread==0) {
            currentmonth = mm;

            printf("Stage 4\n=======\n");

        }

        if (mm == currentmonth) {
            daysinmonthcounted+=1;
            /*other totals*/


        }else if (mm !=currentmonth){


            /*can execute code here as needed such as generating graphs etc*/
            printf("0----+----1----+----2----+----3----+----4----+----5 (x 10, degrees C)\n");
            printf("%d\n", daysinmonthcounted);


            /* make new currentmonth = mm, reset days counted = 1 */
            currentmonth = mm;
            daysinmonthcounted = 1;
        }



        totallinesread+=1;
}

Выход:

0----+----1----+----2----+----3----+----4----+----5 (x 10, degrees C)
31
0----+----1----+----2----+----3----+----4----+----5 (x 10, degrees C)
28
0----+----1----+----2----+----3----+----4----+----5 (x 10, degrees C)
31
0----+----1----+----2----+----3----+----4----+----5 (x 10, degrees C)
30
0----+----1----+----2----+----3----+----4----+----5 (x 10, degrees C)
31
0----+----1----+----2----+----3----+----4----+----5 (x 10, degrees C)
30
0----+----1----+----2----+----3----+----4----+----5 (x 10, degrees C)
31
0----+----1----+----2----+----3----+----4----+----5 (x 10, degrees C)
31
0----+----1----+----2----+----3----+----4----+----5 (x 10, degrees C)
30
0----+----1----+----2----+----3----+----4----+----5 (x 10, degrees C)
31
0----+----1----+----2----+----3----+----4----+----5 (x 10, degrees C)
30
(Note missing december 31 days at the end)

Я обнаружил, что это работает и выводит, как я хотел (в настоящее время печатается только общее количество дней в каждом месяце), но в целом за последний месяц оно пропускается. Я полагаю, что это как-то связано с концом файла (EOF), и поскольку нет следующего значения mm для оператора if (currentmonth != mm), он останавливается и не позволяет мне обрабатывать какие-либо дополнительные вычисления. код на декабрь.

Есть ли способ, чтобы это сработало? Я читал, что scanf(EOF) = -1, который должен работать с currentmonth != mm?

Предполагается, что текстовый файл данных не содержит ошибок или повторяющихся записей и находится в порядке возрастания.

Буду признателен за любую помощь.

Спасибо!

Ответы [ 2 ]

1 голос
/ 02 апреля 2011

[РЕДАКТИРОВАТЬ # 3 - просто показать весь код, а не просто редактировать, чтобы прояснить ситуацию]

int scanned;

while ((scanned = scanf ("% d,% d,% d,% f,% f,% f,% f ", & dd, & mm, & yyyy, & melmax, & melmin, & sydmax, & sydmin)) == 7) {

   if (totallinesread==0) {
       currentmonth = mm;

       printf("Stage 4\n=======\n");

   }

   if (mm == currentmonth) {
       daysinmonthcounted+=1;
       /*other totals*/


   }else if (mm !=currentmonth){


       /*can execute code here as needed such as generating graphs etc*/
       printf("0----+----1----+----2----+----3----+----4----+----5 (x 10, degrees C)\n");
       printf("%d\n", daysinmonthcounted);


       /* make new currentmonth = mm, reset days counted = 1 */
       currentmonth = mm;
       daysinmonthcounted = 1;
   }

   totallinesread+=1;

}

if ((scanned == EOF) && (daysinmonthcounted > 1)){

       /*can execute code here as needed such as generating graphs etc*/
       printf("0----+----1----+----2----+----3----+----4----+----5 (x 10, degrees C)\n");
       printf("%d\n", daysinmonthcounted);

       /* make new currentmonth = mm, reset days counted = 1 */
       currentmonth = mm;
       daysinmonthcounted = 1;
}
1 голос
/ 02 апреля 2011

Вы можете переписать свой цикл, чтобы выйти из середины:

 while(1) {
   failed = 0;
   if (sscanf(....) != 7) {
     mm = 99; /* invalid month */
     failed = 1;
   };
   /* check for month end */
   if (failed) {
      break;
   };
   ...
 }
...