Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > fread не читает весь блок данных


Автор: ksili 10.6.2014, 07:01
Пишу парсер WAV-файлов (под Linux, но это неважно). Т.е. прога должна считывать все чанки и выводить их название и размер. 

В общем-то всё это работает. Читаем каждый заголовок чанка в структуру, парсим, выводим инфу, перескакиваем к следующему чанку и т.д.

Неполадки начались, когда я решил чанк data (самый большой, в котором звуковые данные) не проскакивать (при помощи fseek), а читать в массив (при помощи fread), чтобы потом чего-нибудь с ним делать. 
Делаю в общем-то просто: выделяю массив уже известной мне длины и читаю fread'ом в него. Но считывается всегда меньше данных, чем запрошено. Код этого места такой:
Код

        if(dataChunkLen == 0 && strcmp(outBuffer, "data") == 0)    
        {
            dataChunkLen = pChunkHeader->dLen;
            printf("Position in file - %d.\n", ftell(pFile));

            // копируем звуковые данные в один массив (даже если 2 канала)
            data = new char(dataChunkLen);
            stat = fread((void*)data, sizeof(char), (size_t)dataChunkLen, pFile);
            
            printf("Position in file - %d.\n", ftell(pFile));

            if(stat != dataChunkLen)
            {
                printf("Can't seek data chunk (%d bytes read).\n", stat);
                if(ferror(pFile))    printf("ferror\n");
                    exit(-1);
            }
        }    

Тестирую на файлах размера 100-400 Кб, т.е. ничего особенного. 
printf'ы про позицию в файле добавил, уже когда отлаживался, чтобы проверить, реально останавливается на середине блока данных или нет? 
Вывод например такой:
Цитата

Position in file - 44
Position in file - 548
Can't seek data chunk (504 bytes read).
ferror


Всегда попадаю на  ferror. К сожалению, насколько я понял, ferror не позволяет выяснить, что именно за ошибка произошла.

Я сначала грешил на то, что у меня Linux 64-bit стоит в виртуалке. Но я пересобрал под винду (MS VS, 32-bit) не на виртуалке. Ошибка сохраняется. Только количество реально прочитанных байт другое стало. Вообще, это количество всегда одинаково, т.е. это не какая-то блуждающая ошибка, а что-то стабильное.

В чем может быть проблема?

Автор: ksili 10.6.2014, 07:23
Вот за что я люблю форумы, так это за то, что при попытке написать обстоятельный вопрос, сам доходишь до ответа.

Оказывается, при выделении памяти допущена ошибка - скобки не те. Надо так:
Код

data = new char[dataChunkLen];


Вот только, блин, почему ни один из двух компиляторов не подсказал мне, что тут фигня какая-то написана?

Автор: borisbn 10.6.2014, 09:49
Цитата(ksili @  10.6.2014,  07:23 Найти цитируемый пост)
 почему ни один из двух компиляторов не подсказал мне, что тут фигня какая-то написана?

Потому, что это - не фигня. Ты выделил память под один char и проинициализировал его значением dataChunkLen.
А вот за что действительно можно поругать компилятор, так это за то, что он не спрашивая твоего мнения привёл тип переменной dataChunkLen (скорее всего unsigned int) к char, потеряв при этом три значащих байта и не сказав ни слова

Автор: ksili 10.6.2014, 09:58
borisbn, спасибо.

Ну вот никому довериться нельзя

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)