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

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

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

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

30.08.2012, 01:00. Просмотров 2160. Ответов 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) и в разные переменные просто мистика какая-то...
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) { ...

20
alsav22
5425 / 4820 / 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. Поэтому, если в текстовом файле делается перевод строки, то это добавляет, для бинарного чтения, дополнительные два байта.
1
alsav22
5425 / 4820 / 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;
}
выведет на консоль следующее:
0
Миниатюры
Некорректно читаются данные из бинарного файла  
alsav22
5425 / 4820 / 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;
}
0
Миниатюры
Некорректно читаются данные из бинарного файла  
smertnik
1 / 1 / 0
Регистрация: 06.08.2008
Сообщений: 55
30.08.2012, 02:26  [ТС] #5
то есть чтоб у меня файл читался правильно мне нужно открывать его в текстовом формате? но у меня содержимое бинарное! то есть там встречается вся таблица ASCII! косяков не будет???
0
alsav22
5425 / 4820 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
30.08.2012, 02:30 #6
Цитата Сообщение от smertnik Посмотреть сообщение
то есть чтоб у меня файл читался правильно мне нужно открывать его в текстовом формате?
Я где-то в текстовом формате открываю? И что значит:"...читался правильно..." ? Что, вообще, нужно получить? В чём задача?
0
smertnik
1 / 1 / 0
Регистрация: 06.08.2008
Сообщений: 55
30.08.2012, 08:50  [ТС] #7
я читаю данные файла, потом содержимое буфера перегоняю в биты и уже веду работу с последовательностью бит! и символ '\n' лишний! вобщем остановлюсь наверное на вырезании его! спасибо за помощь, через часик на коде все проверю!
0
alsav22
5425 / 4820 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
30.08.2012, 09:03 #8
Цитата Сообщение от smertnik Посмотреть сообщение
символ '\n' лишний! вобщем остановлюсь наверное на вырезании его!
Не забудьте тогда и '\r' вырезать. Каким методом заполняется сам файл? Возможны варианты, когда в конце ещё и '\0' будет, а в начале строки, например, '\t'. В общем, про другие управляющие символы не забывайте.
0
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;
}
0
alsav22
5425 / 4820 / 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 минут
Я не знаю способа избавиться, при бинарном чтении/записи, от определённых символов, кроме как побайтового чтения/записи и анализа каждого байта, или обработки считанного массива для избавления от ненужных символов и последующей записи в файл.
0
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 буфер без каких либо изменений! я постараюсь после обеда выложить образец!
0
alsav22
5425 / 4820 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
30.08.2012, 12:49 #12
У вас Windows? IDE какая?

Добавлено через 3 минуты
Цитата Сообщение от smertnik Посмотреть сообщение
но при записи в файл без каких либо преобразований как написано выше, записывается буфер без 0D!
В программировании чудес не бывает. Если есть в буфере символы, то они, при бинарной записи, все и запишутся, если нет, то нет. Я в первых постах специально показал, что считывается/записывается при бинарном чтении/записи.
0
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. паковал потому как на сервер не подгружался...
0
Вложения
Тип файла: rar all_res.rar (441 байт, 3 просмотров)
alsav22
5425 / 4820 / 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. Удаление их, в таком случае, будет ошибкой.
0
smertnik
1 / 1 / 0
Регистрация: 06.08.2008
Сообщений: 55
30.08.2012, 15:45  [ТС] #15
это исходный файл делается он в винде, но пишется в него поток бит с устройства! при чтении его в буфере появляется символ 0D перед каждым 0A! и при записи как в моем первом посте, в результирующем файле получается 0D перед каждым 0A! работает только Ваш пример! причем в буфере который пишу в файл 0D есть!
0
30.08.2012, 15:45
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
30.08.2012, 15:45
Привет! Вот еще темы с ответами:

Чтение из файла, не все числа читаются в потоке - 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=...


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

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

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