Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Ввод/Вывод байта в файл 
:(
    Опции темы
cristaloleg
Дата 19.1.2010, 17:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 15.6.2009
Где: Donetsk

Репутация: нет
Всего: нет



Имеется массив фиксированного размера(можно вектор) типа int, в котором хранятся нули и единицы(произвольная последовательность). Нужно сохранить массив в файл, так чтобы файл имел наименьший размер. Естественно без потерь информации.

ЗЫ желательно использовать fstream.

Спасибо.
PM   Вверх
TupDub
Дата 19.1.2010, 17:56 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 46
Регистрация: 21.11.2009

Репутация: нет
Всего: нет



Записать вектор в файл напрямую не получится, это не POD.
Записать массив в файл не сложно, можно так:
Код


int main(int argc, char* argv[])
{
    string filename = "File.dat";
    FILE *file;
    if((file = fopen(filename.c_str(),"w+"))!=false)
    {
         int iData[100];
             for(int wire=0; wire< 100; wire++)
                    iData[wire] = wire;
       
            fwrite(&iData, sizeof(int)*100, 1, file);
           if(file!=false) fclose(file);
    }
   else    cout<<"\n File don't exist! \n"<<endl;

    return 0;
}


Если в твоём массиве только нули и единицы, самый простой вариант кодировать их как разряды двоичного числа. И потом эти числа уже писать в файл.
PM   Вверх
bsa
Дата 19.1.2010, 18:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



Цитата(TupDub @  19.1.2010,  17:56 Найти цитируемый пост)
Записать вектор в файл напрямую не получится, это не POD.
Это не есть правда, так как:
Код
std::vector<int> data;
...
stream.write(reinterpret_cast<const char*>(&*data.begin()), data.size() * sizeof(data.front()));


cristaloleg
Код
std::vector<int> data;
for(int i = 0, s = data.size(); i < s; ) {
   char d = 0;
   for(int j = 7; (j >= 0) && (i < s); --j, ++i)
      if (data[i])
         d |= (1 << j);
   stream.write(&d, 1);
}

PM   Вверх
TupDub
Дата 19.1.2010, 18:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 46
Регистрация: 21.11.2009

Репутация: нет
Всего: нет



bsa, я ошибся... можно. Только придётся писать и размер вектора отдельно, иначе как узнать, сколько читать.
PM   Вверх
zim22
Дата 19.1.2010, 18:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 29
Всего: 69



bsa, &*data.begin() и &data.front() - это одно и тоже.

было:
Код

stream.write(reinterpret_cast<const char*>(&*data.begin()), data.size() * sizeof(data.front()));

стало:
Код

stream.write(reinterpret_cast<const char*>(&data.front()), data.size() * sizeof(data.front()));

smile

Это сообщение отредактировал(а) zim22 - 19.1.2010, 18:38


--------------------
PM MAIL   Вверх
bsa
Дата 19.1.2010, 19:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



Цитата(zim22 @  19.1.2010,  18:37 Найти цитируемый пост)
bsa, &*data.begin() и &data.front() - это одно и тоже.
Уверен? Я знаю, что &data[0] и &*data.begin() это не одно и тоже...

PM   Вверх
cristaloleg
Дата 19.1.2010, 19:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 15.6.2009
Где: Donetsk

Репутация: нет
Всего: нет



Цитата(bsa @  19.1.2010,  17:29 Найти цитируемый пост)
stream.write(&d, 1);


в первом параметре ошибочка получается...первый параметр должен быть 'const char *'

Tак правильно??? :
Код

out.write((char*)&d, 1);



PM   Вверх
zim22
Дата 19.1.2010, 19:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 29
Всего: 69



Цитата(bsa @  19.1.2010,  18:06 Найти цитируемый пост)
Уверен?

на 100% - нет.  но адреса addr1 и addr2 совпадают.
Код

#include "stdafx.h"
#include <vector>

int _tmain(int argc, _TCHAR* argv[])
{
  int arr[] = {10, 99, 34};
  std::vector<int> vi(arr, arr + 3);  
  
  int *addr1 = &*vi.begin();
  int *addr2 = &vi.front();
  return 0;
}




--------------------
PM MAIL   Вверх
bsa
Дата 19.1.2010, 21:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



Цитата(cristaloleg @  19.1.2010,  19:24 Найти цитируемый пост)
в первом параметре ошибочка получается...первый параметр должен быть 'const char *'
преобразование char* -> const char* делается автоматически безо всяких телодвижений.

PM   Вверх
cristaloleg
Дата 19.1.2010, 21:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 15.6.2009
Где: Donetsk

Репутация: нет
Всего: нет



bsa, во всяком случае требуется делать приведение к char*
PM   Вверх
bsa
Дата 19.1.2010, 21:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



Цитата(zim22 @  19.1.2010,  19:26 Найти цитируемый пост)
но адреса addr1 и addr2 совпадают.
Это примерно тоже самое, что высказывание: Раз все тигры полосатые, то все полосатые - тигры

Короче, я спорить не буду, так как сам точно не уверен в обратном. В принципе, &*data.begin(), &data[0] и &data.front() должны возвращать одно и тоже. Разница только в том, что в случае отладки некоторые из методов могут возвращать прокси-объекты, смысл которых сводится к отлову доступа к несуществующим элементам. У Мейерса (Эффективное использование STL) написано, что нужно пользоваться записью вида &data[0], а тех кто говорит про begin() нужно в баню посылать...

Добавлено через 1 минуту и 29 секунд
Цитата(cristaloleg @  19.1.2010,  21:16 Найти цитируемый пост)
bsa, во всяком случае требуется делать приведение к char*
У тебя переменная d точно типа char? Просто нет смысла делать подобное приведение, для указателя на переменную типа char!

PM   Вверх
shuttle
Дата 20.1.2010, 09:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 230
Регистрация: 9.4.2008

Репутация: нет
Всего: нет



Цитата

Записать вектор в файл напрямую не получится, это не POD.


Код

ofstream fout;
fout.open("D:\\vec.txt");
copy(vec.begin(), vec.end(), ostream_iterator<int>(fout," "));
fout.close();

--------------------
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.2783 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.