2017-01-17 11 views
-3

Если я прокомментирую fprintf(pf,"1111");, exe выйдет из строя, и если я сохраню его, я получу 2/3/2011 (только первая запись). Если я попытаюсь закрыть файл, exe также выйдет из строя ,Функция fscanf crash app после первого использования

Действительно ли fscanf обнаруживает конец строки как конец файла и читает нуль?

Я попытался также закрыть (* pf), он все еще падает.

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

Data* d; 
fscanf(pf,"%d",&n); 
d=calloc(n,sizeof(Data*)); 
for(i=0;i<n;i++){ 
    if(fscanf(pf,"%d/%d/%d",&(d[i].zi),&(d[i].luna),&(d[i].an))!=3) break; 
    printf("%d/%d/%d ",d[i].zi,d[i].luna,d[i].an); 
     // fprintf(pf,"1111"); with this I observed that first data can be read 

} 
    fclose(pf); 

вход

3 
2/3/2011 
2/2/2012 
2/2/2016 
+0

звучит как пФ NULL. Вы проверили код возврата с 'fopen'? – bruceg

+2

Каков тип 'd [i]'? Каков тип 'd'? – AlexP

+0

@AlexP - это структура –

ответ

0

исправить так:

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

typedef struct data { 
    int zi, luna, an; 
} Data; 

int main(void){ 
    FILE *pf = fopen("data.txt", "r"); 
    if(pf == NULL){ 
     perror("fopen"); 
     return -1; 
    } 
    Data *d; 
    int n; 
    fscanf(pf, "%d", &n); 
    d = calloc(n, sizeof(Data));//sizeof(Data*) should be sizeof(Data) 
    if(d == NULL){ 
     perror("malloc"); 
     return -2; 
    } 
    for(int i = 0; i < n; i++){//i <= n occurs out ouf bounds, In C 0 origin 
     if(fscanf(pf, "%d/%d/%d", &d[i].zi, &d[i].luna,&d[i].an)!=3) break; 
     printf("%d/%d/%d ", d[i].zi, d[i].luna, d[i].an); 
    } 
    fclose(pf); 
    free(d); 
} 

DEMO

+0

Еще раз спасибо, есть ли второе решение с fseek? Просто интересно ... –

+0

@KingTsunamy 'fseek' не требуется. – BLUEPIXY

1

Добро пожаловать к программированию на языке C.

в C, петли записываются так:

for(i = 0; i < n; i++) 

не так:

for(i = 1; i <= n; i++) 
+1

с использованием 1..3 вызовет проблемы если 'd' объявлен как' struct something d [3] ' – AShelly

+0

Он по-прежнему падает, я сделал это 1, потому что я думал, что он может что-то сделать, но он не может –

1

Помимо других ошибок указывали в вашей программе, реальная причина аварии является: когда вы используете fprintf(), указывает указатель файла в конец файл. По сути, вы пытаетесь использовать fscanf в конце файла во втором вызове и, следовательно, сбое. Чтобы исправить это, вы можете использовать rewind() после вызова fprintf, который перематывает указатель файла на предыдущее местоположение.

fscanf(pf,"%d",&n); 
for(i=1;i<=n;i++){ 
    if(fscanf(pf,"%d/%d/%d",&(d[i].zi),&(d[i].luna),&(d[i].an))!=3) break; 
    printf("%d/%d/%d ",d[i].zi,d[i].luna,d[i].an); 
     fprintf(pf,"1111"); 
    } 
    rewind(fp); 
} 
    fclose(pf); 

EDIT: Как указано в комментариях, это, вероятно, не то, что вы хотите. Лучше всего было бы отслеживать прочитанные байты и использовать fseek, чтобы добраться до нужного вам места после использования fprintf.

+2

Вы правы в обнаружении ошибки, но я не подумайте, что ваше предложение об исправлении будет работать. Вероятно, ОП будет необходимо переосмыслить то, что он/она пытается сделать. Чтение и в то же время запись в один и тот же текстовый файл является ошибочным как концепция. –

+1

Добавление rewind() не будет работать, так как вызов fscanf завершится сбоем из-за того, что «1111» не соответствует спецификатору «% d /% d/& d». Как говорит @Mike, OP нужно переосмыслить то, что он пытается сделать. – FredK

+0

перематывать нужно аргумент pf, и он обновит файл, чтобы вторая и третья строки никогда не были прочитаны. –