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

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

Войти
Регистрация
Восстановить пароль
 
Gdasar
190 / 51 / 10
Регистрация: 18.02.2013
Сообщений: 487
Записей в блоге: 9
Завершенные тесты: 1
#1

Чтение бинарного файла - C++

12.04.2017, 11:44. Просмотров 235. Ответов 11
Метки нет (Все метки)

Здравствуйте.
Есть код чтения бинарного файла:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    FILE *f;
    string tmp;
    char buff[5] = {0};
    f = fopen("data.bin", "rb");
    if(f == NULL)
    {
        return 0;
    }
    int a;
    fread(&buff, 1, 1, f);
    tmp = buff;
    std::istringstream stream(tmp);
    stream >> std::hex >> a;
    cout << a << endl;
    strcpy(buff, "");
    _getch();
    fclose(f);
    return 0;
И в результате получаю 10. Хотя должен получить 65.
C++
1
std::istringstream stream("41");
Выводит 65 - все хорошо.

Собственно вопрос : как мне получить корректное 16-ричное число при чтении?
Спасибо за внимание.
0
Миниатюры
Чтение бинарного файла  
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
12.04.2017, 11:44
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Чтение бинарного файла (C++):

Чтение нескольких структур и одной переменной из бинарного файла. Формат файла имеется - C++
Формат файла состоит из 3 структур и одной переменной. Подробное описание формата во вложении, просьба посмотреть его. У меня возникла...

Чтение бинарного файла - C++
Подскажите пожалуйста как можно правильно открыть бинарный файл не зная структуры? С чего мне начать? Вот пример:

Чтение бинарного файла - C++
Привет! Необходима помощь в таком вопросе - Создал программу для хранения сведений о пользователях(типа такого: введите сведения: ...

Чтение бинарного файла - C++
подскажите пожалуйста как можно из любого файла(*.bmp, *.mp3, *.avi и т.д.) получить двоичное представление этого файла или хотя бы считать...

Чтение из бинарного файла - C++
Уважаемые форумчане! Прошу помочь мне с чтением из бинарного файла. Проблема следующая. Есть функция, которая пишет в бинарный файл -...

Чтение бинарного файла - C++
Добрый Добавлено через 6 минут Добрый день. Не получается прочитать бин. файл. Суть какая: есть файл, в котором записаны дубл...

11
likehood
930 / 789 / 273
Регистрация: 25.12.2016
Сообщений: 2,627
Завершенные тесты: 3
12.04.2017, 11:59 #2
После вызова fread массив buf уже содержит то, что вам нужно.
C++
1
2
3
fread(&buff, 1, 1, f);
int a = buf[0];
std::cout << a;
1
Gdasar
190 / 51 / 10
Регистрация: 18.02.2013
Сообщений: 487
Записей в блоге: 9
Завершенные тесты: 1
12.04.2017, 12:08  [ТС] #3
likehood, и правда
Ещё вопрос : как мне получить число 832194 из следующего 16-ричного числа CB2C2?
C++
1
fread(&buff, 1, 5, f);
Спасибо за ответ.
0
likehood
930 / 789 / 273
Регистрация: 25.12.2016
Сообщений: 2,627
Завершенные тесты: 3
12.04.2017, 12:21 #4
Цитата Сообщение от Gdasar Посмотреть сообщение
fread(&buff, 1, 5, f);
Цитата Сообщение от Gdasar Посмотреть сообщение
CB2C2
Это число занимает в памяти не 5 байтов, а 2.5, так как один байт кодируется двумя hex цифрами.

Добавлено через 1 минуту
Если считать из файла 5 байтов, то это будут байты 41 CB 2C 2C B2.

Добавлено через 2 минуты
Можно прочитать четыре байта и записать их в целое число:
C++
1
2
fread(buff, 1, 4, f); // & перед buff не нужен, buff это и так указатель
int a = *( reinterpret_cast<int*>(buff) );
Добавлено через 1 минуту
А лучше так:
C++
1
2
3
int a;
fread(&a, sizeof(a), 1, f);
std::cout << a;
1
Gdasar
190 / 51 / 10
Регистрация: 18.02.2013
Сообщений: 487
Записей в блоге: 9
Завершенные тесты: 1
12.04.2017, 12:25  [ТС] #5
likehood, понял.
А как же тогда получить нужное мне 16-ричное число?
C++
1
fread(&buff, 1, 3, f);
Вот прочитаю я следующие 3 байта
C++
1
CB2C2C
, а что дальше то? Что-то не пойму.

Добавлено через 2 минуты
В общем, стоит задача : прочитать первый байт, то есть
C++
1
41
и получить из него 2-ное число.
Далее нужно прочитать, как Вы написали, 2,5 байта и перевести их в 10-ное число.
0
likehood
930 / 789 / 273
Регистрация: 25.12.2016
Сообщений: 2,627
Завершенные тесты: 3
12.04.2017, 12:26 #6
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Перевод трёх байтов в целое число:
C++
1
int a = buff[0] + buff[1]*0x100 + buff[2]*0x10000;
Добавлено через 1 минуту
Хотя, если остальная часть массива buff забита нулями, то можно и так, как я написал выше.
1
Gdasar
190 / 51 / 10
Регистрация: 18.02.2013
Сообщений: 487
Записей в блоге: 9
Завершенные тесты: 1
12.04.2017, 12:39  [ТС] #7
Благодарю!
Изначально думал, что 16-ричное число будет проще перевести в 2-е. Но теперь думаю, что просто накотаю функцию для перевода 10-го числа в 2-е.

Добавлено через 11 минут
Вот смотрите:
содержимое бинарного файла
Код
41 CB 2C 2C B2 C7 0A 13 42 CB 2C 1C B2 C8 08 0F
41 - это 65
CB 2C 2 - это 832194
C B2 C7 -это 832199
0A - также число
13 - и это число

далее ещё такой же набор из 5 чисел.

В конце концов я должен получить все 10-ные числа, записанные в файл.
Получаю первое:
C++
1
2
fread(&buff, 1, 1, f);
a = buff[0];
Как далее мне получить 2 и 3 числа?
CB 2C 2 - это 832194
C B2 C7 -это 832199
0
likehood
930 / 789 / 273
Регистрация: 25.12.2016
Сообщений: 2,627
Завершенные тесты: 3
12.04.2017, 12:42 #8
А числа точно хранятся в таком формате, с разрывом посередине байта? Как-то странно это выглядит.
0
Gdasar
190 / 51 / 10
Регистрация: 18.02.2013
Сообщений: 487
Записей в блоге: 9
Завершенные тесты: 1
12.04.2017, 12:43  [ТС] #9
likehood, да, именно так они и хранятся.
Есть идеи по поводу того, как их получить?
0
likehood
930 / 789 / 273
Регистрация: 25.12.2016
Сообщений: 2,627
Завершенные тесты: 3
12.04.2017, 13:02 #10
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от Gdasar Посмотреть сообщение
Есть идеи по поводу того, как их получить?
Можно сначала разбить байты на половинки, а потом обратно их объединить. Например так (код не проверял).
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
int join(char *buff, int n);
 
void foo()
{
    char buff[] = { 0x41, 0xCB, 0x2C, 0x2C, 0xB2, 0xC7, 0x0A, 0x13 };
    const int len = 8;
    char halfByteBuff[len*2];
 
    // split
    for (int i=0; i<len; i++)
    {
        halfByteBuff[i*2]   = buff[i] >> 4;
        halfByteBuff[i*2+1] = buff[i] & 0x0F;
    }
 
    // join
    int a = join(&halfByteBuff[0], 2); // a == 0x41
    int b = join(&halfByteBuff[2], 5); // b == 0xCB2C2
    int c = join(&halfByteBuff[7], 5); // c == 0xCB2C7
}
 
int join(char *buff, int n)
{
    int x = 0;
    for (char *p = buff+n-1; p >= buff; p--)
    {
        x = x*16 + *p;
    }
 
    return x;
}
Добавлено через 2 минуты
Только порядок байтов у меня не правильный, надо цикл в 25 строке заменить на
C++
1
for (char *p = buff; p < buff+n; p++)
1
Gdasar
190 / 51 / 10
Регистрация: 18.02.2013
Сообщений: 487
Записей в блоге: 9
Завершенные тесты: 1
12.04.2017, 16:38  [ТС] #11
likehood, как я понял:
41 - это 0100 0001
Данное выражение сдвигает первые 4 бита на 4 позиции вправо
C++
1
buff[i] >> 4
в итоге получаем 0000 0100 - это 4

Вторая операция - И(битовое И)
C++
1
buff[i] & 0x0F
0F - это 0000 1111
0100 0001 & 0000 1111 = 0000 0001

Тут вроде как все понятно Надеюсь, верно всё понял.

Вот только код
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
char buff[] = { 0x41, 0xCB, 0x2C, 0x2C, 0xB2, 0xC7, 0x0A, 0x13 };
    const int len = 8;
    char halfByteBuff[len*2];
 
    // split
    for (int i=0; i<len; i++)
    {
        halfByteBuff[i*2]   = buff[i] >> 4;
        halfByteBuff[i*2+1] = buff[i] & 0x0F;
    }
 
    // join
    int a = join(&halfByteBuff[0], 2); // a == 0x41
    int b = join(&halfByteBuff[2], 5); // b == 0xCB2C2
    int c = join(&halfByteBuff[7], 5); // c == 0xCB2C7
 
    cout << a << endl;
    cout << b << endl;
    cout << c << endl;
Выводит следующее:
65
-216382
766407
Понять не могу из-за чего так происходит.
0
likehood
930 / 789 / 273
Регистрация: 25.12.2016
Сообщений: 2,627
Завершенные тесты: 3
12.04.2017, 16:51 #12
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Нужно заменить char на unsigned char, иначе неправильно выполняется операция buff[i] >> 4.
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
38
39
40
41
42
43
44
45
#include <iostream>
 
int join(unsigned char *buff, int n);
 
void foo()
{
    unsigned char buff[] = { 0x41, 0xCB, 0x2C, 0x2C, 0xB2, 0xC7, 0x0A, 0x13 };
    const int len = sizeof(buff)/sizeof(buff[0]);
    unsigned char halfByteBuff[len*2];
 
    // split
    for (int i=0; i<len; i++)
    {
        halfByteBuff[i*2]   = buff[i] >> 4;
        halfByteBuff[i*2+1] = buff[i] & 0x0F;
    }
 
    for (int i = 0; i < len*2; i++)
        std::cout << std::hex << (int) halfByteBuff[i] << ' ';
    std::cout << "\n";
 
    // join
    int a = join(&halfByteBuff[0], 2); // a == 0x41
    int b = join(&halfByteBuff[2], 5); // b == 0xCB2C2
    int c = join(&halfByteBuff[7], 5); // c == 0xCB2C7
    std::cout << std::hex << a << "\n";
    std::cout << std::hex << b << "\n";
    std::cout << std::hex << c << "\n";
}
 
int join(unsigned char *buff, int n)
{
    int x = 0;
    for (unsigned char *p = buff; p < buff+n; p++)
    {
        x = x*16 + *p;
    }
 
    return x;
}
 
int main()
{
    foo();
}
1
12.04.2017, 16:51
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
12.04.2017, 16:51
Привет! Вот еще темы с ответами:

Чтение бинарного файла - C++
как получить доступ к произвольному адресу файла? Нужно отправить файл через ком порт но не с 0 а с адреса 1а000 в цикле по 0х100 байт. с 0...

Чтение из бинарного файла - C++
Здравствуйте. У меня имеется некий класс Product, объекты которого хранятся в объекте класса Vector. Есть функция записи вектора в бинарный...

Чтение из бинарного файла - C++
Всем приветы. Подскажите или помогите, пожалста. Есть вот такая штука: #include &quot;stdafx.h&quot; #include &lt;iostream&gt; #include...

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


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

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

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