2016-04-20 2 views
2

Я использую Debian и написал veeeery простой файл программы синтаксического анализа в C. Файл Я хочу открыть длиной около 32k строк, со строгим форматом:файла дескриптора исчезающей/аннулируя

number,number\n 
number,number\n 
and so on ... 

Мой код :

int main(int argc, char* argv[]) 
{ 
    char data = 0; 
    int addr = 0; 
    char buf[50] = {0}; 

    FILE* myfile = fopen("eelocdump.txt", "r"); 

    if(myfile == NULL) 
    { 
     printf("File open error\n"); 
     return 1; 
    } 

    while (fgets(buf, 50, myfile) != NULL) 
    { 
     sscanf(buf, "%5d,%3d\n", &addr, &data); 
     printf("%d,%d\n", addr, data); 
    } 

    fclose(myfile); 

    return 0; 
} 

Для некоторых нечетных причин я не понимаю, мой код читает первую строку файла, записывает его, то ошибку сегментации. Примерно через час, потраченный на это, я узнал, что вызов sscanf заставил файловый дескриптор быть установленным в NULL.

Я нашел «исправить», что я едва осмеливаюсь назвать так:

while (fgets(buf, 50, myfile) != NULL) 
    { 
     sscanf(buf, "%5d,%3d\n", &addr, &data); 
     printf("%d,%d\n", addr, data); 

     myfile = myfile; 
    } 

Добавление этого очевидное утверждение делает мой код работы, выписывая все 32k линии. Это почти удовлетворяет, так как это ничего не меняет. (а также не должно влиять на файловый дескриптор)

Не могли бы вы помочь мне решить эту проблему правильно? Мне не очень нравится называть это «magic».

Заранее благодарен,

+4

'char data = 0;' -> 'int data = 0;' потому что '% 3d' для int. – BLUEPIXY

+0

Я тестировал gcc и отлично работает ('gcc (Ubuntu 4.8.4-2ubuntu1 ~ 14.04.1) 4.8.4') – BlackBear

+0

скомпилировать его с' -Wall' '-Wextra' gcc должен предупредить о неправильном использовании' scanf 'и' printf' – fghj

ответ

2

Эти линии непоследовательны.

char data = 0; 
/* ... */ 
    sscanf(buf, "%5d,%3d\n", &addr, &data); 

data является char, так что это 1 байт памяти. Вы работаете на Linux, если у вас 64-разрядная машина, int, вероятно, 8 байт. Таким образом, ваш sscanf() выполняет переполнение памяти, которое может что-то сделать: перезапись других переменных, повреждение стека и т. Д. Установка другой переменной в null, вероятно, является одной из менее катастрофических вещей, которые она может сделать.

+0

Как упоминалось ранее BLUEPIXY, правильно. Спасибо за дополнительное объяснение. :) – Domack