С программа вылетает при вызове fopen - PullRequest
0 голосов
/ 12 мая 2018

Я здесь новичок, и у меня есть проблема, которую я не могу решить, выполнив поиск в Интернете.

Моя программа просто падает, когда я снова вызываю fopen. Просто небольшое описание: Программа читает файлы строка за строкой. Есть два возможных формата для этих строк, поэтому я должен различать их. Когда файл находится в формате, это соответствует ветке "else". Программа отлично работает без сбоев. Однако другой формат, который приводит к появлению ветки «if», приводит к сбою. Надеюсь, вам достаточно части исходного кода.

    FILE *f = fopen("DATA.txt", "a+");
    for (int m = 0; m<listsize; m += 1) {
    .
    .
    .
    FILE *CSV = fopen(name, "r");
    FILE *pufferfile = fopen("puf.txt", "w+");        
    .
    .
    .
    char puffer[90];
    while (fgets(puffer, 90, CSV))
    {
        fputs(puffer, pufferfile);
        fseek(pufferfile, 0, SEEK_SET);
        if ((strstr(puffer, "\"")) != NULL) {
            fscanf(pufferfile, "%d,%d/%d/%d,%d:%d:%d,\"  %[^'\"]%s%*[ \"]%s  %[^'\"]%s  %[^'\"]%s\n", &row, &month, &day, &year, &hours, &minutes, &seconds, w_h, we, wj, w_t);
            fseek(pufferfile, 0, SEEK_SET);
            h_0 = atoi(w_h);
            h_0 += ((float)atoi(w_h + (strlen(w_h)) - 1) / (float)10);
            hum = h_0;
            t_0 = atoi(w_t);
            t_0 += ((float)atoi(w_t + (strlen(w_t)) - 1) / (float)10);
            temp = t_0;
        }
        else {
            fscanf(pufferfile, "%d,%d/%d/%d,%d:%d:%d,%f,%s\n", &row, &month, &day, &year, &hours, &minutes, &seconds, &hum, we);
            fseek(pufferfile, 0, SEEK_SET);
            t_1 = (int)we[4] - 48;
            t_2 = (int)we[5] - 48;
            t_0 = (int)we[7] - 48;
            if (we[6] == ',') {
                t_3 = 0;
            }
            else {
                t_3 = t_0;
            }
            temp = t_1 * 10 + t_2 + t_3 / 10;
        }
        fprintf(f, "      %02d.%02d.%d\t ;\t %02d:%02d:%02d\t ;\t    %.1f\t ;\t %.1f\n", day, month, year, hours, minutes, seconds, temp, hum);

    }
    fclose(CSV);
    fclose(pufferfile);
    remove(name);


}
remove("puf.txt");
fclose(f);

int index = 0;
FILE *woo = fopen("DATA_daily.txt", "w+"); //HERE it crashes

Редактировать: Извините, я добавил еще несколько строк в код, чтобы вы могли лучше понять его. Он не падает непосредственно в ветке «если». Дело в том, что если программа читает файл, отформатированный определенным образом, она выбирает ветвь if. И каким-то образом происходит сбой при вызове последнего "fopen (" DATA_daily.txt "," w + ");". Те же данные, отформатированные так, что программа выбирает ветвь else, не приводят к сбою. Позвольте мне объяснить это в ближайшее время. У меня есть список (размером по длине) имен файлов. Программа открывает его, читает строки и решает, как строка отформатирована. В соответствии с этим он считывает значения и помещает их в другой файл (здесь «DATA.txt»). После сбоя программы я вижу файл DATA.txt, и он выглядит нормально. Каждая строка там написана.

Возможные два формата строки выглядят так:

1,4/4/2017,13:03:42,"  000028,9",       %RH,"  000023,1",  DEGREE C ---> resulting in the if-branch, causes crash
and
1,4/4/2017,13:03:42,28.9,       %RH,23.1,  DEGREE C  ---> resulting in the else branch, NO crash

1 Ответ

0 голосов
/ 12 мая 2018

Я заметил, что ваш код в ветке "if" не проверяет возвращаемые значения из fscanf, что является первым исправлением.Например:

rc = fscanf(...);
if ( rc != 11 )
{
  // handle error
}

Далее я бы проверил, как вы определили w_h и w_t, и изменил бы% s.Я только что проверил страницу MSDN для функции scanf (), и она предупреждает, что вы всегда должны указывать ширину для формата% s (например, вместо этого использовать% 32s), чтобы избежать переполнения буфера.

Я также гарантировал бы, что w_hи w_t заканчиваются нулем перед передачей их в качестве аргумента strlen или atoi.Например:

char w_t[MAXLEN];
rc = fscanf(...);
if ( rc != 11 ) { /* handle error */ }
w_t[sizeof(w_t)-1] = '\0';
a = atoi(w_t);

Но теперь я заметил, что на самом деле вы написали

atoi(w_t + (strlen(w_t))

, который не будет ничего полезного, потому что, даже если w_t успешно завершен нулем, это пройдетв atoi указатель на завершающий нулевой байт.Я не знаю, что из этого сделает atoi, но, вероятно, вернет 0. Всегда.

В любом случае, это первые вещи, которые я бы исправил.Как сказал кто-то еще, вы доберетесь куда-нибудь быстрее, если будете использовать отладчик.Или printfs.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...