Форум программистов, компьютерный форум CyberForum.ru

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 15, средняя оценка - 5.00
smertnik
1 / 1 / 0
Регистрация: 06.08.2008
Сообщений: 55
#1

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

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

столкнулся с такой проблемой и не могу найти ей объяснение.
есть код читающий содержимое двоичного файла:
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) и в разные переменные просто мистика какая-то...
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
30.08.2012, 01:00     Некорректно читаются данные из бинарного файла
Посмотрите здесь:

Строки читаются из текстового файла функцией fgets и указатели на них помещаются в структуру данных... C++
Некорректно выводятся данные C++
Редактирование бинарного файла C++
C++ Дамп бинарного файла
Данные записываются в файл некорректно C++
Считывание бинарного файла C++
Вывести данные из бинарного файла в окно графическом режима C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
alsav22
5413 / 4809 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
30.08.2012, 01:12     Некорректно читаются данные из бинарного файла #2
Тут разница между бинарным чтением/записью и текстовым. При текстовом чтении/записи перевод строки в Windows и DOS состоит из двух символов: \r\n (13 и 10), в UNIX - из одного \n (10), в Mac OS - из одного \r (13). Именно 0D - это '\r', а '\n' - 0A. При текстовам чтении/записи \r\n обрабатываются в Windows как один символ '\n', при бинарном - как два байта со значениями 0D и 0A. Поэтому, если в текстовом файле делается перевод строки, то это добавляет, для бинарного чтения, дополнительные два байта.
alsav22
5413 / 4809 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
30.08.2012, 01:39     Некорректно читаются данные из бинарного файла #3
Предположим есть файл с тремя строками:
C++
1
2
3
12345
12345
12345
После каждой строки, кроме последней, нажимался Enter. Тогда такой код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <fstream>
using namespace std;
 
 
 int main()
{
    fstream f("1.txt", ios::in | ios::binary);
    char ch;
    while (f.read(&ch, 1))
    {
        cout << hex << uppercase << (int)ch << " ";
        if (ch == '\n') cout << endl;
    }
    
    cout << endl;
    system("pause");
    return 0;
}
выведет на консоль следующее:
Миниатюры
Некорректно читаются данные из бинарного файла  
alsav22
5413 / 4809 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
30.08.2012, 02:04     Некорректно читаются данные из бинарного файла #4
Этот код ещё и запишет содержимое файла "1.txt" в файл "2.txt", но без символов '\r' и '\n'. В файле "2.txt" будет:
C++
1
123451234512345
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
#include <iostream>
#include <fstream>
using namespace std;
 
 
 int main()
{
    fstream f("1.txt", ios::in | ios::binary);
    fstream fw("2.txt", ios::out | ios::binary);
    char ch;
    while (f.read(&ch, 1))
    {
        cout << hex << uppercase << (int)ch << " ";
        if (ch == '\n') cout << endl;
        
        if (ch != '\r' && ch != '\n')
            fw.write((const char*)&ch, 1);
    }
    f.close();
    fw.close();
    
    fw.open("2.txt", ios::in | ios::binary);
    
    cout << endl << endl;
    while (fw.read(&ch, 1))
    {
        cout << hex << uppercase << (int)ch << " ";
        if (ch == '\n') cout << endl;
    }
    
    fw.close();
    
    cout << endl;
    system("pause");
    return 0;
}
Миниатюры
Некорректно читаются данные из бинарного файла  
smertnik
1 / 1 / 0
Регистрация: 06.08.2008
Сообщений: 55
30.08.2012, 02:26  [ТС]     Некорректно читаются данные из бинарного файла #5
то есть чтоб у меня файл читался правильно мне нужно открывать его в текстовом формате? но у меня содержимое бинарное! то есть там встречается вся таблица ASCII! косяков не будет???
alsav22
5413 / 4809 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
30.08.2012, 02:30     Некорректно читаются данные из бинарного файла #6
Цитата Сообщение от smertnik Посмотреть сообщение
то есть чтоб у меня файл читался правильно мне нужно открывать его в текстовом формате?
Я где-то в текстовом формате открываю? И что значит:"...читался правильно..." ? Что, вообще, нужно получить? В чём задача?
smertnik
1 / 1 / 0
Регистрация: 06.08.2008
Сообщений: 55
30.08.2012, 08:50  [ТС]     Некорректно читаются данные из бинарного файла #7
я читаю данные файла, потом содержимое буфера перегоняю в биты и уже веду работу с последовательностью бит! и символ '\n' лишний! вобщем остановлюсь наверное на вырезании его! спасибо за помощь, через часик на коде все проверю!
alsav22
5413 / 4809 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
30.08.2012, 09:03     Некорректно читаются данные из бинарного файла #8
Цитата Сообщение от smertnik Посмотреть сообщение
символ '\n' лишний! вобщем остановлюсь наверное на вырезании его!
Не забудьте тогда и '\r' вырезать. Каким методом заполняется сам файл? Возможны варианты, когда в конце ещё и '\0' будет, а в начале строки, например, '\t'. В общем, про другие управляющие символы не забывайте.
smertnik
1 / 1 / 0
Регистрация: 06.08.2008
Сообщений: 55
30.08.2012, 11:32  [ТС]     Некорректно читаются данные из бинарного файла #9
там всякие символы попадаются, но они бед не создают! мне важно любой символ в биты перегнать, а 0D просто лишним появлялся! вобщем я испробовал все комбинации fread fwrite, handle read write, в различных режимах и чтения и записи и везде такой косяк... но вот предложенный вариант с fstream дал то что нужно! причем в буфере 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
#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[statbuf.st_size];   \\в примере размер файла 369 байт
 
    fstream f(path.c_str(), ios::in | ios::binary);
    fstream fw("rez.txt", ios::out | ios::binary);
    
    f.read(bytef, statbuf.st_size);
    length=strlen(bytef);     \\после чтения bytef стал 374 байта (+5 0D)
    fw.write(bytef, statbuf.st_size);    \\записал 369 байт и получилась копия path.c_str() без 0D
 
    f.close();
    fw.close();
    
    return 0;
}
alsav22
5413 / 4809 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
30.08.2012, 12:13     Некорректно читаются данные из бинарного файла #10
Цитата Сообщение от smertnik Посмотреть сообщение
записал 369 байт и получилась копия path.c_str() без 0D
У вас в файле, что один 0D? А 0А куда дели? Если вы записали на 5 байт меньше, это не значит, что избавились от 5 символов 0D. Я не вижу в коде, как происходит избавление от 0D и от 0А. Как определяете размер файла? Если у вас файл 369 байтов, откуда появляются ещё 5? strlen() показывает количество печатных символов, без '\n' и '\r'.

Добавлено через 13 минут
Для того, чтобы узнать сколько байт в файле, нужно открыть его для чтения в бинарном режиме и сделать следующее:
C++
1
2
3
fstream f("1.txt", ios::in | ios::binary);
f.seekg(0, ios::end);
cout << f.tellg() << endl;
Добавлено через 11 минут
Я не знаю способа избавиться, при бинарном чтении/записи, от определённых символов, кроме как побайтового чтения/записи и анализа каждого байта, или обработки считанного массива для избавления от ненужных символов и последующей записи в файл.
smertnik
1 / 1 / 0
Регистрация: 06.08.2008
Сообщений: 55
30.08.2012, 12:40  [ТС]     Некорректно читаются данные из бинарного файла #11
да... тема на грани абсурда... размер файла я беру в stat(path.c_str(),&statbuf); не открывая его!
в моем конкретном файле 5 0A и соответственно в буфер добавляется 5 0D! но при записи в файл без каких либо преобразований как написано выше, записывается буфер без 0D! записывается ровно то что было в исходном файле! я сверяю по hex кодам! мистика но работает! я бы скинул образец, но трудно перенести файл на эту машину...
strlen() у меня почему-то возвращает количество символов в bytef с учетом всех что там есть!
избавляюсь я от 0D в отдельном цикле, делаю новый массив в котором пропускаю 0D если после него стоит 0A, но это уже другая история! пишу я в fw буфер без каких либо изменений! я постараюсь после обеда выложить образец!
alsav22
5413 / 4809 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
30.08.2012, 12:49     Некорректно читаются данные из бинарного файла #12
У вас Windows? IDE какая?

Добавлено через 3 минуты
Цитата Сообщение от smertnik Посмотреть сообщение
но при записи в файл без каких либо преобразований как написано выше, записывается буфер без 0D!
В программировании чудес не бывает. Если есть в буфере символы, то они, при бинарной записи, все и запишутся, если нет, то нет. Я в первых постах специально показал, что считывается/записывается при бинарном чтении/записи.
smertnik
1 / 1 / 0
Регистрация: 06.08.2008
Сообщений: 55
30.08.2012, 13:22  [ТС]     Некорректно читаются данные из бинарного файла #13
XP стоит и C++ Builder 6.0.
про чудеса я все прекрасно понимаю! поэтому и не успокаиваюсь на достигнутом! хочу понять почему именно так! ведь по логике эти строчки
length=strlen(bytef); \\после чтения bytef стал 374 байта (+5 0D)
fw.write(bytef, statbuf.st_size); \\записал 369 байт и получилась копия path.c_str() без 0D
должны в fw записать первые 369 байт из bytef, а оставшиеся 5 не трогать! эти 0D не в конце, а по буферу раскинуты, а он их убирает! исходный и результирующие файлы полностью идентичны!
вот образец!

P.S. паковал потому как на сервер не подгружался...
Вложения
Тип файла: rar all_res.rar (441 байт, 3 просмотров)
alsav22
5413 / 4809 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
30.08.2012, 15:02     Некорректно читаются данные из бинарного файла #14
Цитата Сообщение от smertnik Посмотреть сообщение
исходный и результирующие файлы полностью идентичны!
Не пойму. Если идентичны, и в исходном фале управляющие символы были, то значит они никуда и не делись? Позже посмотрю архив. Сейчас ухожу.

Добавлено через 11 минут
Никаких 0D в файле нет. Есть 5 0A. И 369 байт - это вместе с пятью 0A. Интересно, куда делись 0D ? Сам файл как изготовлялся? В Windows или может в UNIX ? Там символ новой строки - один символ 0A. Подробнее позже.

Добавлено через 1 час 16 минут
В этом файле текстовые строки записаны или просто какие-то значения? Ведь коды 0A и 0D трактуются как управляющие символы, если речь идёт о тексте, а если это файл неких значений, то 0A и 0D это просто байты со значением 10 и 13. Удаление их, в таком случае, будет ошибкой.
smertnik
1 / 1 / 0
Регистрация: 06.08.2008
Сообщений: 55
30.08.2012, 15:45  [ТС]     Некорректно читаются данные из бинарного файла #15
это исходный файл делается он в винде, но пишется в него поток бит с устройства! при чтении его в буфере появляется символ 0D перед каждым 0A! и при записи как в моем первом посте, в результирующем файле получается 0D перед каждым 0A! работает только Ваш пример! причем в буфере который пишу в файл 0D есть!
alsav22
5413 / 4809 / 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.
Миниатюры
Некорректно читаются данные из бинарного файла  
alsav22
5413 / 4809 / 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;
}
Миниатюры
Некорректно читаются данные из бинарного файла  
smertnik
1 / 1 / 0
Регистрация: 06.08.2008
Сообщений: 55
30.08.2012, 17:13  [ТС]     Некорректно читаются данные из бинарного файла #18
уже мозг кипит... сейчас остановил программу посмотрел в буфере уже нет этих символов! но они 100% были! потому как при дальнейшей обработке у меня вылезали лишние биты! именно по коду 0D! тоже сделал счетчик он не находит 0D, но еще раз повторюсь они были в буфере если остановить выполнение и просмотреть его содержимое! но при записи в файл моим способом 0D появляется! но это уже объясняется постом в самом начале! fstream решает эту проблему! ну вот вроде разобрались! спасибо большое!

я уже писал что ваш метод через fstream работает как надо!
alsav22
5413 / 4809 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
30.08.2012, 17:46     Некорректно читаются данные из бинарного файла #19
Цитата Сообщение от smertnik Посмотреть сообщение
но при записи в файл моим способом 0D появляется!
Я уже не со своим кодом разбираюсь, а с вашим. В 16 посте ваш код из первого поста, там нет fstream и всё так же работает нормально. Никаких дополнительных символов. Вы когда пишите:
Цитата Сообщение от smertnik Посмотреть сообщение
но при записи в файл моим способом 0D появляется!
, имеете ввиду, запись в файл, того что считали в bytef ?
Потом вот это:
Цитата Сообщение от smertnik Посмотреть сообщение
но еще раз повторюсь они были в буфере если остановить выполнение и просмотреть его содержимое!
В какой момент остановку делали? Может это заморочки отладчика, что-нибудь не то показывал?
Что-то странное... Не могут байты неизвестно откуда появляться.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
30.08.2012, 18:27     Некорректно читаются данные из бинарного файла
Еще ссылки по теме:

Построение идеально сбалансированного дерева, значения читаются из текстового файла C++
C++ Ошибка в программе. Данные записываются в файл некорректно
Чтение из файла, не все числа читаются в потоке C++
C++ Записать\прочесть данные в\из бинарного файла в инкапсулированну структуру
C++ Извлечь данные из бинарного файла

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

Или воспользуйтесь поиском по форуму:
smertnik
1 / 1 / 0
Регистрация: 06.08.2008
Сообщений: 55
30.08.2012, 18:27  [ТС]     Некорректно читаются данные из бинарного файла #20
имеете ввиду, запись в файл, того что считали в bytef ? ------ да именно так! писал и fwrite и write.

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

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

у меня мысли такие: fwrite и write пишут по правилам из второго поста и поэтому добавляют 0D
Yandex
Объявления
30.08.2012, 18:27     Некорректно читаются данные из бинарного файла
Ответ Создать тему
Опции темы

Текущее время: 19:55. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru