Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
smertnik
1 / 1 / 0
Регистрация: 06.08.2008
Сообщений: 55
#1

Некорректно читаются данные из бинарного файла - C++

30.08.2012, 01:00. Просмотров 2545. Ответов 29
Метки нет (Все метки)

столкнулся с такой проблемой и не могу найти ей объяснение.
есть код читающий содержимое двоичного файла:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <fcntl.h>
#include <sys\stat.h>
char *bytef;
void read_f()
{
    FILE *openfile;
    openfile=fopen(path.c_str(),"rb");
    if (openfile)
    {
        struct stat statbuf;
        stat(path.c_str(),&statbuf);
        bytef=new char[statbuf.st_size];
        fread (bytef,statbuf.st_size,1,openfile);
    };
fclose(openfile);
}
}
чтение происходит без ошибок, но сделав паузу и просматривая содержимое переменной bytef наблюдаю
появление символов '\n' там где их в реале нет! при записи содержимого переменной в файл, обнаружил закономерность:
символ '\n' , 0D в шестнадцатиречиной системе, появляется только перед символом 0A который непечатаемый, но в файле есть! и после чтения из файла bytef становится больше на добавленное количество символов! сделал цикл вырезающий '\n' перед 0А, но при записи в файл у меня '\n' начало затирать байты перед 0А вобще бред какой-то... пробовал читать из файла и писать разными методами (read, fread) и в разные переменные просто мистика какая-то...
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
30.08.2012, 01:00
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Некорректно читаются данные из бинарного файла (C++):

Не читаются данные из txt-файла - C++
5 3 2E5 1.7E5 0.001 0 1000 0.5 10 1000 0.5 10 1000 0.5 10 1000 0.5 10 1000 0.5 10 a b c d ...

Извлечь данные из бинарного файла - C++
Написать функцию которая извлекает данные из из бинарного файла в структуру. Обязательный параметр - номер требуемой записи

Вывести данные из бинарного файла в окно графическом режима - C++
Подскажите, пожалуйста, как вывести данные из бинарного файла в окно графического режима? outtextxy не помогает.

Записать\прочесть данные в\из бинарного файла в инкапсулированну структуру - C++
Здравствуйте форумчане. Как записать\прочесть данные в\из бинарного файла в инкапсулированну структуру такого вида? struct obj { ...

Создание бинарного дерева из бинарного файла - C++
struct Bin { string name; string city; int players; int score; }; void ReadFromBin(Point*&amp; Tree) { Bin q;

Создание бинарного дерево из бинарного файла - C++
struct Bin { string name; string city; int players; int score; }; void ReadFromBin(Point*&amp; Tree) { ...

29
alsav22
5437 / 4832 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
30.08.2012, 16:39 #16
Немного переделанный ваш код из первого поста:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <fcntl.h>
#include <sys\stat.h>
#include <iostream>
#include <fstream>
using namespace std;
 
char *bytef;
void read_f()
{
    FILE *openfile;
    openfile = fopen("all_res.bin", "rb");
    if (openfile)
    {
        //struct stat statbuf;
        //stat(path.c_str(), &statbuf);
        bytef = new char[369];
        fread (bytef, 369, 1, openfile);
    }
 
    fclose(openfile);
}
 
 int main()
 {
    read_f();
    int n = 0;
    for (int i = 0; i < 369; i++) // вывод на консоль содержимого bytef
    {
         cout << hex << uppercase << (int)((unsigned char)bytef[i]) << ' ';
         if (bytef[i] == 0x0D) n++; // если встретился байт со занчением 0D.
    }
 
    cout << endl << endl << "D = " << n << endl; // сколько встретилось 0D.
    
    system("pause");
    return 0;
 }
Вместо statbuf.st_size поставил 369 и закоментировал структуру, потому что у меня её нет. Результат работы. Побайтовый вывод (через пробел) содержимого буфера bytef, после считывания в него файла. Вывод количетсва найденных байтов со значением 0D.
0
Миниатюры
Некорректно читаются данные из бинарного файла  
alsav22
5437 / 4832 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
30.08.2012, 17:01 #17
Код из 9 поста. Результат тот же. Никаких 0D в буфере нет.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>
#include <fstream>
#include <sys\stat.h>
using namespace std;
 
char *bytef; 
 
 int main()
{
    //int length;
    //struct stat statbuf;
    //stat(path.c_str(),&statbuf);
    bytef = new char[369]; // размер файла 369 байт
 
    fstream f("all_res.bin", ios::in | ios::binary);
    fstream fw("rez.bin", ios::out | ios::binary);
    
    f.read(bytef, 369); // считал 369 байт.
    //length=strlen(bytef); Непременимо. Даёт ошибку, так как в bytef не строка.
    fw.write(bytef, 369);   // записал 369 байт. 
    f.close();
    fw.close();
 
    int n = 0;
    for (int i = 0; i < 369; i++) // вывод на консоль содержимого bytef
    {
         cout << hex << uppercase << (int)((unsigned char)bytef[i]) << ' ';
         if (bytef[i] == 0x0D) n++; // если встретился байт со занчением 0D.
    }
 
    cout << endl << endl << "D = " << n << endl; // сколько встретилось 0D.
    
    system("pause");
    return 0;
}
0
Миниатюры
Некорректно читаются данные из бинарного файла  
smertnik
1 / 1 / 0
Регистрация: 06.08.2008
Сообщений: 55
30.08.2012, 17:13  [ТС] #18
уже мозг кипит... сейчас остановил программу посмотрел в буфере уже нет этих символов! но они 100% были! потому как при дальнейшей обработке у меня вылезали лишние биты! именно по коду 0D! тоже сделал счетчик он не находит 0D, но еще раз повторюсь они были в буфере если остановить выполнение и просмотреть его содержимое! но при записи в файл моим способом 0D появляется! но это уже объясняется постом в самом начале! fstream решает эту проблему! ну вот вроде разобрались! спасибо большое!

я уже писал что ваш метод через fstream работает как надо!
0
alsav22
5437 / 4832 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
30.08.2012, 17:46 #19
Цитата Сообщение от smertnik Посмотреть сообщение
но при записи в файл моим способом 0D появляется!
Я уже не со своим кодом разбираюсь, а с вашим. В 16 посте ваш код из первого поста, там нет fstream и всё так же работает нормально. Никаких дополнительных символов. Вы когда пишите:
Цитата Сообщение от smertnik Посмотреть сообщение
но при записи в файл моим способом 0D появляется!
, имеете ввиду, запись в файл, того что считали в bytef ?
Потом вот это:
Цитата Сообщение от smertnik Посмотреть сообщение
но еще раз повторюсь они были в буфере если остановить выполнение и просмотреть его содержимое!
В какой момент остановку делали? Может это заморочки отладчика, что-нибудь не то показывал?
Что-то странное... Не могут байты неизвестно откуда появляться.
0
smertnik
1 / 1 / 0
Регистрация: 06.08.2008
Сообщений: 55
30.08.2012, 18:27  [ТС] #20
имеете ввиду, запись в файл, того что считали в bytef ? ------ да именно так! писал и fwrite и write.

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

Может это заморочки отладчика, что-нибудь не то показывал? ------ там содержимое файла один в один но с добавкой 0D.

у меня мысли такие: fwrite и write пишут по правилам из второго поста и поэтому добавляют 0D
0
alsav22
5437 / 4832 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
31.08.2012, 09:52 #21
Цитата Сообщение от smertnik Посмотреть сообщение
у меня мысли такие: fwrite и write пишут по правилам из второго поста и поэтому добавляют 0D
Бинарное чтение\запись ничего не добавляет, в отличие от текстового. Во втором посте кода нет. Все другие ваши коды (1 и 9 пост) я проверил. Результат выложен. Если сейчас всё нормально работает, то можно на этом и остановиться, или выложите пример кода, где происходит что-то непонятное. Больше информации к размышлению нет.
1
ErikPshat
0 / 0 / 0
Регистрация: 26.08.2016
Сообщений: 53
01.03.2018, 02:29 #22
У меня аналогичная проблема. Утилитка производит чтение размера из файла по такому-то адресу.
Размер файла естесственно записан в хейдере в бинарном виде = 0AFB0150.
Утилитка считывает эти данные из файла и пишет эти же данные в другой файл на выходе.
И что странно, все файлы различных размеров записываются корректно, а вот если размер начинается с 0A, как в данном примере, то спереди добавляется 0D. И количество байт становится больше на 1, что приводит к неработоспособности бинарного файла.
0
nd2
2820 / 2390 / 851
Регистрация: 29.01.2016
Сообщений: 8,004
01.03.2018, 02:49 #23
ErikPshat, значит ты не в бинарном режиме открываешь файл, а в текстовом.
1
ErikPshat
0 / 0 / 0
Регистрация: 26.08.2016
Сообщений: 53
01.03.2018, 04:08 #24
Не могли бы вы мне помочь исправить эту неприятность?
Во вложение я положил 2 небольших демо-файла, у которых размер начинается с 0A
Простейшая утилитка с одним маленьким исходником и готовая консольная. Она не поддерживает drag&drop, но тоже хотелось бы чтоб помогли.
Можете попробовать через консоль натравить эти демо на утилитку и на выходе появится папка с тремя файлами.
Там размеры прописываются в двух функциях друг за другом:
  • 0x000000D0 (функция) 0x00000008 (длина строки) 0x00000008 (длина строки) 0xFFFFFFFFFFFFFFFF (размер файла 8 байт).
  • 0x000000CE (функция) 0x00000008 (длина строки) 0x00000008 (длина строки) 0xFFFFFFFFFFFFFFFF (размер файла 8 байт).
В общем в исходнике всё увидите, думаю объяснять тут по ним не нужно.
0
Вложения
Тип файла: zip Bubble_Maker.zip (32.9 Кб, 7 просмотров)
Black Fregat
2396 / 1211 / 302
Регистрация: 31.05.2009
Сообщений: 4,800
01.03.2018, 04:28 #25
ErikPshat, там нигде режим не указан вообще.
Всюду, где fopen(..., "r") и fopen(..., "w") нужно поставить fopen(..., "rb") и, соответственно, fopen(..., "wb")

Добавлено через 2 минуты
То есть, добавить в строку буквочку b - бинарный режим
1
ErikPshat
0 / 0 / 0
Регистрация: 26.08.2016
Сообщений: 53
01.03.2018, 04:43 #26
Black Fregat, о, спасибо большое! Проверил, теперь всё работает.
Я понял, т.е. rb - read byte, wb - write byte. То есть идёт указание именно на чтение и запись бинарного кода.

А ещё по ходу не могли бы подсказать по поводу Drag & Drop? Чтобы просто кидать файл на экзешник. Я пытался и так и эдак, но никак не получается, одни ругательства )))
0
Black Fregat
2396 / 1211 / 302
Регистрация: 31.05.2009
Сообщений: 4,800
01.03.2018, 12:50 #27
Какие ругательства? Прямо так должно работать, "из коробки", ничего менять не надо
0
ErikPshat
0 / 0 / 0
Регистрация: 26.08.2016
Сообщений: 53
01.03.2018, 20:28 #28
Black Fregat, ой, прошу прощения, ввёл в заблуждение.
Функция "drag and drop" по факту работает. Это я что-то запамятовал. И вроде она как положено выполняется, то есть, подставляет в аргумент "Полный путь". Я так понимаю это здесь
C++
1
pkg = fopen (argv[1], "rb");
Но дело в том, что этот путь у меня так же прописывается в файл. А мне нужно прописывать туда только название файла.
То есть, нужно обрезать путь и при записи оставить только название.

Я думаю это что-то нужно химичить здесь в argv[1]:
C++
1
2
3
4
  write_pdb (out1, path, argv[1], argc >= 2 ? argv[2]: NULL,
      &pkg_header, htonl (HEADER5_MAGIC_VALUE));
  write_pdb (out2, path, argv[1], argc >= 2 ? argv[2]: NULL,
      &pkg_header, htonl (0));
Я же пока только новичок и пытаюсь разобраться, но вот как это реализовать?

Добавлено через 3 часа 37 минут
Ну так что, это не реально отрезать путь из аргумента argv[1]?

В батнике я знаю, что это довольно просто отрезать от полного пути %%~dpni только имя файла типа так %%~ni.
А вот в С++ до меня это как-то сложно доходит.
0
nd2
2820 / 2390 / 851
Регистрация: 29.01.2016
Сообщений: 8,004
01.03.2018, 21:50 #29
Цитата Сообщение от ErikPshat Посмотреть сообщение
Ну так что, это не реально отрезать путь из аргумента argv[1]?
Реально, тему создай.
1
ErikPshat
0 / 0 / 0
Регистрация: 26.08.2016
Сообщений: 53
02.03.2018, 01:22 #30
Цитата Сообщение от nd2 Посмотреть сообщение
Реально, тему создай.
Создал: Как отрезать путь из аргумента argv[1] и оставить только название файла?
0
02.03.2018, 01:22
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
02.03.2018, 01:22
Привет! Вот еще темы с ответами:

Чтение из файла, не все числа читаются в потоке - C++
Здравствуйте! Написал программку которая создает массив из случайных символов, записывает его в файл и читает потом файл в другой массив....

Построение идеально сбалансированного дерева, значения читаются из текстового файла - C++
Разработать программу построения идеально сбалансированного дерева, элементами которого являются целые числа, которые читаются из...

Строки читаются из текстового файла функцией fgets и указатели на них помещаются в структуру данных... - C++
Вообщем вот такое задание: Строки читаются из текстового файла функцией fgets и указатели на них помещаются в структуру данных. Элементы...

Некорректно выводятся данные - C++
в програмке не выводятся значения для y. на экран выводится как x= -5.00 z= 5.00 y=-10.485428 x= -4.50 z= 4.50 y=-8.819977 x=...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
30
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru