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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Помогите разобраться 
:(
    Опции темы
klein
Дата 25.3.2007, 02:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 111
Регистрация: 30.5.2006
Где: Київ

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



       Добрый день.
    Пишу програму на билдере. Ее суть заключается в том, чтобы она считывала побитно файл, заносила значения каждого бита в ячейку масива, потом второй масив неким алгоритмом присваивал значения первого (в даном случае просто buf2[b2]=buf1[b1]) а потом второй масив записывался в файл. Первоначально писал так, чтобы файл считывался в двумерный масив (какбы по строчкам с определенной длинной), но получалось так, что в файл записывало только 260 первых символов, тогда решил написать так, чтобы весь файл считывался в одномерный масив , а потом записывался в файл. Проблема повторилась. Файлы получаются по 304 байта и записывается только "верхний" кусок исходного файла. Это первая проблема, которую я не могу понять .
    Вторую проблему я понимаю, но не знаю как исправить. Она заключается в том, что с файла в масив считываются символы, а надо чтобы значения бит (0,1). В потокахуказывал ios::binary.   Буферы типа бул работают  не коректно(bool buf1[sizeof iuf],buf2[sizeof iuf]; ) .
   Подведу черту и конкретизирую вопросы:
         1.) Почему пишется только "шапка" файла?
         2.) Как считывать в масив значения битов?
   Делал поиск по форуму, что сильно помогло составить даный код :

Код

#include <fstream.h>
#include <stdio.h>
#include "Unit555.h"
#include <iostream.h>
#include <stdio.h>
#include <cstdio>
#pragma package(smart_init)
#pragma resource "*.dfm"
#pragma hdrstop
TForm1 *Form1;
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner) {}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  OpenDialog1->Execute();
  SaveDialog1->Execute();
   {
     int  ni; //количество битов
     ifstream iuf(OpenDialog1->FileName.c_str(),ios::binary);//открытие в бинарном режиме для чтения
     ofstream onf(SaveDialog1->FileName.c_str(),ios::binary);//открытие в бинарном режиме для записи
     char buf1[sizeof iuf],buf2[sizeof iuf];
     int b1,b2;
     ni=sizeof iuf;//присвоение значения размера файла
     for (b1=0;b1<ni;b1++) iuf.get(buf1[b1]);
     b1=0 ;
     for (b2=0;b2<ni;b2++) {buf2[b2]=(buf1[b1]); b1++; };//присвоение значения buf1 к buf2 для следующих операций(здвиг битов)
     for (b2=0 ; b2<ni; b2++) onf.put(buf2[b2]);//вывод буфера buf2 в файл
        iuf.close();
        onf.close();
   }
}




    На возникшие вопросы при поиске аналогию не нашол.
    Заранее благодарен!

Модератор: Название темы должно отражать ее суть!

Это сообщение отредактировал(а) Earnest - 26.3.2007, 10:49
PM MAIL   Вверх
zkv
Дата 25.3.2007, 08:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


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

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



Цитата(klein @  25.3.2007,  02:38 Найти цитируемый пост)
1.) Почему пишется только "шапка" файла?

все просто:
Цитата(klein @  25.3.2007,  02:38 Найти цитируемый пост)
char buf1[sizeof iuf],buf2[sizeof iuf];

оператор sizeof вовсе не возвращает размер занимаемый файлом на диске, он возвращает место занимаемое переменной данного типа в оперативной памяти.
Цитата(klein @  25.3.2007,  02:38 Найти цитируемый пост)
2.) Как считывать в масив значения битов?

не совсем понятно, скажу только, что минимальная  адресуемая ячейка памяти - байт а не бит, а что вы в этот байт засунете (или извлечете) - дело ваше, личное.
PM MAIL   Вверх
threef
Дата 25.3.2007, 11:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Сначала ознакомьтесь с битовыми операциями. Затем ознакомьтесь с операциями блочного чтения/ записи. Сразу обнаружите свои ошибки.
PM MAIL   Вверх
klein
Дата 25.3.2007, 17:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 111
Регистрация: 30.5.2006
Где: Київ

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



  По существу второго вопроса понял ошибку. Минимальный квант считывания байт. Потом надо будет уже к нему  применить битовую маску и проверить - установлен ли конкретный бит.
 По существу первого вопроса сейчас разбираюсь как узнать размер файла на диске для выделения размера буфера. Мысль пока не закончена, но направления два:  
1) пропустить через цикл , и заждую итерацию инкремировать счетчик байтов 
Код

ni=0;while(!inf.eof()) {buf1[ni] = inf.get()
;  ni++;});
 2) с помощью указателя считывания seekg
Код

  ifile.seekg(0, std::ios::end);
  int size = ifile.tellg();
  ifile.seekg(0, std::ios::beg);
  char *buf = new char[size+1];

 Позже отпишусь.
PM MAIL   Вверх
klein
Дата 26.3.2007, 12:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 111
Регистрация: 30.5.2006
Где: Київ

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



Вот получился такой код:
Код

  OpenDialog1->Execute();
  SaveDialog1->Execute();
   {
     ifstream inf(OpenDialog1->FileName.c_str(),ios::binary);
     ofstream ouf(SaveDialog1->FileName.c_str(),ios::binary);
     inf.seekg(0, std::ios::end);//перемещение указателя в конец файла
     int size = inf.tellg();//количество байт от начала до конца файла(весь файл)
     inf.seekg(0, std::ios::beg);//возвращение указателя считывания в начало файла
     char *buf1 = new char[size+1];//Динамическое выделение памяти буфера под файл
     char *buf2 = new char[size+1];//Динамическое выделение памяти буфера под файл
     size = 0;//Обнуление счетчика
     while (!inf.eof()) buf1[size++] = inf.get();//Чтение
     for (int i=0; i < size-1; ++i) ouf.put(buf1[i]);//Запись
     delete [] buf1;
     inf.close();
     ouf.close();
   }


  Он работает, (просто копирует файл) но при больших файлах выдает ошибку . Мои предположения в том, что весь файл не в состоянии записаться в оперативную память(char *buf1 = new char[size+1]; ).
 Как розделить память буфера на "куски"?  
PM MAIL   Вверх
Earnest
Дата 26.3.2007, 15:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

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



Цитата(klein @  26.3.2007,  13:08 Найти цитируемый пост)
но при больших файлах выдает ошибку 

Какую?

Код у тебя довольно бессмысленный:
1) Какой смысл выделять память под целый файл, если ты копируешь посимвольно?
2) зачем тебе buf2? ты его не используешь, да еще и не уничтожаешь.
3) чтобы избежать проблем с большими файлами, читай-пиши блоками:
   определи размер файла file_size,
   выдели буфер разумной длины (buf_size)
   читай блок и сразу пиши:
Код

   while (file_size)
   {
       size_t cnt = std::min (buf_size, file_size);      
       in.read (buf, cnt);
       out.write (buf, cnt);
       file_size-=buf_size;
   }



Это сообщение отредактировал(а) Earnest - 26.3.2007, 15:49


--------------------
...
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

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

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


 




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


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

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