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

Запись в файл значения int (hex,ascii) - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 28, средняя оценка - 4.79
MyNameIsPetr
0 / 0 / 0
Регистрация: 04.09.2011
Сообщений: 10
04.09.2011, 14:37     Запись в файл значения int (hex,ascii) #1
Задача: Записать в файл значение int == 0x52494646 ("RIFF" in ASCII form)
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include "stdafx.h"
#include "iostream"
#include "fstream"
using namespace std;
 
int _tmain(int argc, _TCHAR* argv[])
{
    fstream PCMFile("output.wav",std::ios::binary|std::ios::out|std::ios::in);
    unsigned long int ChunkID = 0x52494646;//"RIFF" in ASCII form
    
        cout.write((char*)&ChunkID,sizeof(ChunkID));//Вывод на экран
    PCMFile.write((char*)&ChunkID,sizeof(ChunkID));//Запись в файл
    
        PCMFile.close();
    cout << endl;
    system("pause");
    return 0;
}
Вопрос: Так почему же получается FFIR, а не ожидаемый RIFF?
Какой код записи будет верным?

P.S. Использовать char строки не хочется.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
niXman
Эксперт C++
 Аватар для niXman
3133 / 1445 / 49
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
04.09.2011, 14:53     Запись в файл значения int (hex,ascii) #2
потому что: http://ru.wikipedia.org/wiki/%D0%9F%...82%D0%BE%D0%B2
MyNameIsPetr
0 / 0 / 0
Регистрация: 04.09.2011
Сообщений: 10
04.09.2011, 15:02  [ТС]     Запись в файл значения int (hex,ascii) #3
Буквально вчера читал, и догадывался что причина именно в этом. Вот только как элегантно решить такую задачу?(с++)
Проблемы совместимости

Запись многобайтового числа из памяти компьютера в файл или передача по сети требует соблюдения соглашений о том, какой из байтов является старшим, а какой младшим. Прямая запись ячеек памяти приводит к возможным проблемам при переносе приложения с платформы на платформу.
niXman
Эксперт C++
 Аватар для niXman
3133 / 1445 / 49
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
04.09.2011, 16:32     Запись в файл значения int (hex,ascii) #4
C++
1
unsigned long int ChunkID = 0x46464952;
так?
MyNameIsPetr
0 / 0 / 0
Регистрация: 04.09.2011
Сообщений: 10
04.09.2011, 23:43  [ТС]     Запись в файл значения int (hex,ascii) #5
Цитата Сообщение от niXman Посмотреть сообщение
C++
1
unsigned long int ChunkID = 0x46464952;
так?
Да ... Это наиболее простое решение, но у меня ни одна такая переменная.
Спасибо, за то, что дали верное направление.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int ToBigEndian(int i)// перевод к порядку байт от большего к меньшему(сетевому)
{
    //unsigned char c[sizeof(int)];
    int r=0;
    if (is_bigendian())
    {
        return i;
    }
    else
    {
        for(int f=0,sd=0;f<sizeof(int);f++,sd+=8)
        {
            //c[f] = i >> sd;
            //r += (int)(c[f]<<(24-sd));
            r += (int)(((i >> sd)&255)<<(24-sd));// работает только с &255
        }
    }
    return r;
}
Источники:
1.http://www.ibm.com/developerworks/ru...endianc/#list7
2.http://ru.wikipedia.org/wiki/%D0%9F%...82%D0%BE%D0%B2

Всё работает, но остается ещё один вопрос. Зачем делать &255? (Примеры в первом источнике)
Число1 конъюнкция 255, должна по идеи вернуть то же число1. Что я не понимаю?
grizlik78
Эксперт С++
 Аватар для grizlik78
1884 / 1416 / 102
Регистрация: 29.05.2011
Сообщений: 2,961
05.09.2011, 01:55     Запись в файл значения int (hex,ascii) #6
Цитата Сообщение от MyNameIsPetr Посмотреть сообщение
Всё работает, но остается ещё один вопрос. Зачем делать &255? (Примеры в первом источнике)
Число1 конъюнкция 255, должна по идеи вернуть то же число1. Что я не понимаю?
Это выделение одного (младшего) байта.
Например:
0x46464952 & 0xFF == 0x52
(0x46464952 >> 8) & 0xFF == 0x49
(0x46464952 >> 16) & 0xFF == 0x46
(0x46464952 >> 24) & 0xFF == 0x46


Цитата Сообщение от MyNameIsPetr Посмотреть сообщение
unsigned long int ChunkID = 0x52494646;
Я бы рекомендовал вместо unsigned long int использовать, по возможности, тип uint32_t.
Если заголовка <cstdint> или <stdint.h> нет, то вместо unsigned long int лучше использовать просто unsigned int, так как на большинстве платформ его размер равен 32 битам. Но в этом случае очень желательно сделать какую-нибудь проверку, например
C++
1
assert(sizeof(unsigned int) == 4);
хотя невыполнение этого условия не значит, что int не 32-битный.
В Windows можно использовать DWORD.

Ну, про функцию htonl() по ссылкам написано. Жаль, что её нет в стандартной библиотеке, а в разных системах она объявляется в разных заголовках.

Если использовать boost, то там ещё такого монстрика можно найти
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
#include <stdint.h>
#include <boost/asio/detail/socket_ops.hpp>
 
#define HTONL(x) boost::asio::detail::socket_ops::host_to_network_long(x)
 
int main()
{
    uint32_t a = HTONL(0x11223344);
    std::cout << std::hex << a << std::endl;
 
    return 0;
}
accept
4838 / 3237 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
05.09.2011, 04:59     Запись в файл значения int (hex,ascii) #7
Цитата Сообщение от MyNameIsPetr
P.S. Использовать char строки не хочется.
эндианство может меняться на разных компьютерах
в символьном массиве будет переносимо
OstapBender
 Аватар для OstapBender
581 / 519 / 35
Регистрация: 22.03.2011
Сообщений: 1,585
05.09.2011, 07:27     Запись в файл значения int (hex,ascii) #8
MyNameIsPetr, а что вам мешает использовать обычный потоковый ввод вывод?
MyNameIsPetr
0 / 0 / 0
Регистрация: 04.09.2011
Сообщений: 10
05.09.2011, 12:36  [ТС]     Запись в файл значения int (hex,ascii) #9
grizlik78, спасибо БОЛЬШОЕ, всё стало ясно.
Функция в предыдущем сообщении, по моему замыслу должна работать с любым размером int.
is_bigendian - проверка порядка байт в машине.
C++
1
#define is_bigendian()((*(char*)&one) == 0)
accept, OstapBender
Да, сейчас я осознаю, что проще и наверное правильней было бы
C++
1
file << "RIFF";
На момент написания предыдущих сообщений было ещё не ясно сколько переделывать переменных надо будет.
Переписывать код, или оставить как есть...
"Premature optimization is the root of all evil". D. E. Knuth
Как бы намекает
grizlik78
Эксперт С++
 Аватар для grizlik78
1884 / 1416 / 102
Регистрация: 29.05.2011
Сообщений: 2,961
05.09.2011, 12:51     Запись в файл значения int (hex,ascii) #10
Цитата Сообщение от MyNameIsPetr Посмотреть сообщение
Функция в предыдущем сообщении, по моему замыслу должна работать с любым размером int.
Ну я, в общем-то не про функцию, а про само значение. Если переменная окажется 8 байт размером, то так и запишутся 8 байт, хоть и переставленные, хотя надо было 4 байта.

Цитата Сообщение от MyNameIsPetr Посмотреть сообщение
C++
1
file << "RIFF";
Если файл бинарный, то лично мне не очень нравится использование форматированного вывода. Я бы, наверное, сделал что-то вроде
C++
1
file.write("RIFF", 4);
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.09.2011, 15:22     Запись в файл значения int (hex,ascii)
Еще ссылки по теме:

Std::count << std::hex << (long) 0x0a; Как сделать, чтоб от HEX значения ноль при выводе не убирался? C++
Если HEX одного файла заменить на HEX другого, то изменится ли файл и будет ли работоспособным? C++
C++ Считывание\запись int из файла\в файл

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

Или воспользуйтесь поиском по форуму:
MyNameIsPetr
0 / 0 / 0
Регистрация: 04.09.2011
Сообщений: 10
05.09.2011, 15:22  [ТС]     Запись в файл значения int (hex,ascii) #11
Да, всё верно, принял к сведению.
Yandex
Объявления
05.09.2011, 15:22     Запись в файл значения int (hex,ascii)
Ответ Создать тему
Опции темы

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