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

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

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 28, средняя оценка - 4.79
MyNameIsPetr
0 / 0 / 0
Регистрация: 04.09.2011
Сообщений: 10
#1

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

04.09.2011, 14:37. Просмотров 3740. Ответов 10
Метки нет (Все метки)

Задача: Записать в файл значение 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 строки не хочется.
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
04.09.2011, 14:37
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Запись в файл значения int (hex,ascii) (C++):

error C2664: itoa: невозможно преобразовать параметр 1 из 'int *' в 'int' + запись в файл - C++
Подскажите пожалуйста как быть... в конструктор приходит *int и мне нужно создать файл, с именем таким же, что и значение, которое приходит...

Если HEX одного файла заменить на HEX другого, то изменится ли файл и будет ли работоспособным? - C++
Привет, если два файла a.exe(калькулятор) и b.exe(выводит строку &quot;Hello World&quot;) Если открыть файл b.exe в HEX-редакторе и подменить его...

Считывание\запись int из файла\в файл - C++
как считать Int из файла потом его же записать?

Запись масива int-ов в бинарный файл - C++
Задание звучит так: Напишите функцию bool writeIntArray(const int arr, int size, FILE *fp), которая записывает содержимое массива int'ов...

Перевод из HEX в ASCII и ещё кое - что - C++
Народ, как строку в HEX типа 3A 30 31 30 36 перевести в ASCII типа :0106 ? А как наоборот? А самое интересное, как из HEX перевести...

Запись структуры в файл, но стуктура цифровая (int) - C++
нужно записать структуру с цифровыми полями Но запись в файле должна быть структурированной.. _____

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

Запись многобайтового числа из памяти компьютера в файл или передача по сети требует соблюдения соглашений о том, какой из байтов является старшим, а какой младшим. Прямая запись ячеек памяти приводит к возможным проблемам при переносе приложения с платформы на платформу.
0
niXman
Эксперт C++
3135 / 1447 / 49
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
04.09.2011, 16:32 #4
C++
1
unsigned long int ChunkID = 0x46464952;
так?
0
MyNameIsPetr
0 / 0 / 0
Регистрация: 04.09.2011
Сообщений: 10
04.09.2011, 23:43  [ТС] #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. Что я не понимаю?
0
grizlik78
Эксперт С++
1911 / 1443 / 112
Регистрация: 29.05.2011
Сообщений: 3,000
05.09.2011, 01:55 #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;
}
2
accept
4822 / 3243 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
05.09.2011, 04:59 #7
Цитата Сообщение от MyNameIsPetr
P.S. Использовать char строки не хочется.
эндианство может меняться на разных компьютерах
в символьном массиве будет переносимо
1
OstapBender
583 / 521 / 35
Регистрация: 22.03.2011
Сообщений: 1,585
05.09.2011, 07:27 #8
MyNameIsPetr, а что вам мешает использовать обычный потоковый ввод вывод?
1
MyNameIsPetr
0 / 0 / 0
Регистрация: 04.09.2011
Сообщений: 10
05.09.2011, 12:36  [ТС] #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
Как бы намекает
0
grizlik78
Эксперт С++
1911 / 1443 / 112
Регистрация: 29.05.2011
Сообщений: 3,000
05.09.2011, 12:51 #10
Цитата Сообщение от MyNameIsPetr Посмотреть сообщение
Функция в предыдущем сообщении, по моему замыслу должна работать с любым размером int.
Ну я, в общем-то не про функцию, а про само значение. Если переменная окажется 8 байт размером, то так и запишутся 8 байт, хоть и переставленные, хотя надо было 4 байта.

Цитата Сообщение от MyNameIsPetr Посмотреть сообщение
C++
1
file << "RIFF";
Если файл бинарный, то лично мне не очень нравится использование форматированного вывода. Я бы, наверное, сделал что-то вроде
C++
1
file.write("RIFF", 4);
0
MyNameIsPetr
0 / 0 / 0
Регистрация: 04.09.2011
Сообщений: 10
05.09.2011, 15:22  [ТС] #11
Да, всё верно, принял к сведению.
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.09.2011, 15:22
Привет! Вот еще темы с ответами:

Почему запись int в файл происходит в обратном порядке? - C++
Разбирался в способе сохранения структур в файле, наткнулся на вот такой пример: int a = 'abcd'; FILE* WriteFile; char...

Std::count << std::hex << (long) 0x0a; Как сделать, чтоб от HEX значения ноль при выводе не убирался? - C++
сабж...( std::count &lt;&lt; std::hex &lt;&lt; (long) 0x0a; ) выводится просто a, вместо 0а, а надо чтоб было именно 0а... куда делся setw,...

HEX string => int - C++
Доброе время суток. Возникла необходимость преобразовать шестнадцатиричную строку в int. Пробовал разные вариации с sprintf, но они не...

Внедрить hex в указатель int - C++
Здравствуйте, собственно как внедрить hex в память, нужно нечто подобное: int *i = new int(); i = 0xFF; i = 0xFF; i = 0xFF; ...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
05.09.2011, 15:22
Ответ Создать тему
Опции темы

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