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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Параметры fopen, Правильность задания параметров 
:(
    Опции темы
Shmell
  Дата 14.4.2012, 12:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Здравствуйте! Хочу открыть файл для чтения в двоичном (не преобразующем) режиме для работы с ним, как с последовательностью нулей и единиц. 
Для этого надо поставить в вызове параметры r - для чтения и b - двоичный режим. 
Написал вот так:

Код

fopen ("c:\\test.txt", "rb");


Правильно ли это? Как надо пристыковать b?

Добавлено через 4 минуты и 32 секунды
Компилятор на такое заполнение не ругается.

Добавлено через 11 минут и 20 секунд
Гм, посмотрел в Википедии, вроде бы правильно все написал...
PM MAIL   Вверх
alexvs11
Дата 14.4.2012, 12:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


hell is here
**


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

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



Цитата(Shmell @  14.4.2012,  12:35 Найти цитируемый пост)
Компилятор на такое заполнение не ругается.

что за компилятор и как ругается?
PM MAIL   Вверх
KaZepKa
Дата 14.4.2012, 13:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(alexvs11 @  14.4.2012,  12:59 Найти цитируемый пост)
что за компилятор и как ругается? 

Не ругается, потому что правильно

PM MAIL   Вверх
Shmell
Дата 14.4.2012, 13:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(alexvs11 @  14.4.2012,  12:59 Найти цитируемый пост)
что за компилятор и как ругается? 

Да C++Builder 2010 (Rad Studio который).
KaZepKa прав, надо вводить подряд параметры, я же сначала ввел их через запятую и в кавычках каждый. smile 
PM MAIL   Вверх
bsa
Дата 14.4.2012, 13:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(Shmell @  14.4.2012,  13:35 Найти цитируемый пост)
Хочу открыть файл для чтения в двоичном (не преобразующем) режиме для работы с ним, как с последовательностью нулей и единиц.

ты так никогда его не откроешь. Потому что нет такого режима.
двоичный режим - это режим, при котором комбинация символов "\r\n" не преобразуется к "\n". И все. Более того, этот режим существует только для операционок производства Microsoft и аналогов. В мире unix такого режима нет.
Чтобы получить набор нулей и единиц, ты должен читать байты из файла, а затем вручную преобразовывать в двоичную форму (читай про операторы << и &).
PM   Вверх
Shmell
Дата 14.4.2012, 13:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



bsa, и как это можно организовать??? smile

Добавлено через 8 минут и 27 секунд
Код

 FILE *SecretFile;              //указатель на скрываемый файл
BYTE *textbuf;                   //буфер файла

void OpenFile()
/* Открывает файл для чтения */
{
  //само окрытие
if ((SecretFile = fopen ("c:\\test.txt", "r")) == NULL){
  MessageBox (NULL, "Не удалось открыть скрываемый файл.", "Ошибка", MB_OK | MB_ICONERROR);
  ERR_NO_FILE = true;
  }
else MessageBox (NULL, "Файл готов к работе!","Info", MB_OK | MB_ICONINFORMATION);

  //определение размера файла
  fseek(SecretFile, 0, SEEK_END); //узнать конец файла
  FILE_SIZE = ftell (SecretFile); //определить его размер
  fseek(SecretFile, 0, SEEK_SET); //поставить указатель назад

  //выделение памяти под файл - инициализация массива textbuf
if ((textbuf = (BYTE*) malloc(sizeof(BYTE*) * FILE_SIZE )) == NULL){
  MessageBox (NULL, "Не удалось выделить память под файл","Ошибка", MB_OK | MB_ICONERROR);
  ERR_NO_FILE = true;
 }
else MessageBox (NULL, "Доступна память для файла!","Info", MB_OK | MB_ICONINFORMATION);

  //считать файл в буфер
   size_t count = FILE_SIZE/8;
   size_t size = 1;
if (fread(textbuf, size, count, SecretFile) != count){   //чтение в буфер
  MessageBox (NULL, "Не удалось считать файл в буфер","Ошибка", MB_OK | MB_ICONERROR);
  ERR_NO_FILE = true;
  }
else MessageBox (NULL, "Файл скопирован в буфер не полностью!","Info", MB_OK | MB_ICONINFORMATION);
}


Вот я создал массив textbuf, состоящих из элементов  BYTE (размер которых = 1 байт). Считал в этот массив файл. Т.е. я вроде как разбил файл на байты. Иначе говоря, я должен получить массив, в котором содержатся байты файла по одному.


bsa, этого достаточно, чтобы считать законченным первый этап манипуляций, указанных Вами:

Цитата(bsa @  14.4.2012,  13:17 Найти цитируемый пост)
Чтобы получить набор нулей и единиц, ты должен читать байты из файла, а затем вручную преобразовывать в двоичную форму (читай про операторы << и &). 

?
PM MAIL   Вверх
Shmell
Дата 14.4.2012, 13:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



А по поводу второго этапа, есть вот такая функция:

Код

int *ByteToBinary (BYTE val)
/* Разбивает исходный Байт на биты. Возвращает массив из восьми элементов
   Каждый Nй элемент соответствует Nму биту.
   Принимает значения 1 или 0
*/
{           int *mass = new int[8];
            int t, i;
            for (t = 128, i = 0; t > 0; t /= 2, i++)
            {
                if ((val & t) != 0) mass[i] = 1;
                else if ((val & t) == 0) mass[i] = 0;
            }
  return mass;
}


Добавлено через 22 секунды
Она подойдет?
PM MAIL   Вверх
feodorv
Дата 14.4.2012, 14:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

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



Цитата(bsa @  14.4.2012,  14:17 Найти цитируемый пост)
В мире unix такого режима нет.

Цитата(Shmell @  14.4.2012,  14:43 Найти цитируемый пост)
MessageBox (

Где-то здесь затаилась нестыковочка))))


Цитата(bsa @  14.4.2012,  14:17 Найти цитируемый пост)
двоичный режим - это режим, при котором комбинация символов "\r\n" не преобразуется к "\n". И все.

Не совсем так. Не всё))) В двоичном режиме чтение файла не прерывается символом '\0' smile 


Цитата(Shmell @  14.4.2012,  13:35 Найти цитируемый пост)
fopen ("c:\\test.txt", "rb");

Это абсолютно правильно)))


Цитата(Shmell @  14.4.2012,  14:43 Найти цитируемый пост)
size_t count = FILE_SIZE/8;

Размер файла задаётся в байтах, а не в битах (это если деление на 8 задумано по этой причине)


Цитата(Shmell @  14.4.2012,  14:43 Найти цитируемый пост)
if ((textbuf = (BYTE*) malloc(sizeof(BYTE*) * FILE_SIZE )) == NULL)

Почему sizeof(BYTE*)???


Цитата(Shmell @  14.4.2012,  14:43 Найти цитируемый пост)
if (fread(textbuf, size, count, SecretFile) != count){   //чтение в буфер
  MessageBox (NULL, "Не удалось считать файл в буфер","Ошибка", MB_OK | MB_ICONERROR);
  ERR_NO_FILE = true;
  }
else MessageBox (NULL, "Файл скопирован в буфер не полностью!","Info", MB_OK | MB_ICONINFORMATION);

Здесь логическая ошибка: при правильном чтении будет MessageBox (NULL, "Файл скопирован в буфер не полностью!","Info",...

Это сообщение отредактировал(а) feodorv - 14.4.2012, 14:18


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
Shmell
Дата 14.4.2012, 14:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Решил поэкспериментировать с данной темой. Написал тоже, только для консольного приложения. Вот оно:

Код

//---------------------------------------------------------------------------

#include <vcl.h>
#include <stdio.h>
#include <iostream.h>
#pragma hdrstop

#include <tchar.h>
//---------------------------------------------------------------------------

#pragma argsused

FILE *SecretFile;              //указатель на скрываемый файл
BYTE *textbuf;                 //буфер файла

unsigned int FILE_SIZE = 0;
int *bitarray = new int[8];

int *ByteToBinary (BYTE val);
//---------------------------------------------------------------------------

void main(int argc, char argv[])
{
  /* Открывает файл для чтения */
  cout<<"Opening file"<<endl;
  cin.get();
  //само окрытие
if ((SecretFile = fopen ("c:\\test.txt", "r")) == NULL){
    cout<<"Could not to open file!!!"<<endl;
    cin.get();
  }
else cout<<"Successfully opening"<<endl;
cin.get();
  //определение размера файла
  fseek(SecretFile, 0, SEEK_END); //узнать конец файла
  FILE_SIZE = ftell (SecretFile); //определить его размер
  fseek(SecretFile, 0, SEEK_SET); //поставить указатель назад
  //выделение памяти под файл - инициализация массива textbuf
if ((textbuf = (BYTE*) malloc(sizeof(BYTE*) * FILE_SIZE )) == NULL){
 cout<<"Failed to malloc for file"<<endl;
  cin.get();
 }

else cout<<"Successfully malloc for file"<<endl;
cin.get();
  //считать файл в буфер
   size_t count = FILE_SIZE/8;
   size_t size = 1;
if (fread(textbuf, size, count, SecretFile) != count){   //чтение в буфер
  cout<<"Error of reading file!!!"<<endl;
   cin.get();
  }

else cout<<"Successfylly reading to memory!!!"<<endl;
cin.get();
unsigned int i = 0;
int j = 0;
//for (i = 0; i < count; i++) {
    //printf("Byte %d: %b", i, textbuf(count));

//}

for (i = 0; i < count; i++) {

       bitarray = ByteToBinary (textbuf);
       printf ("Byte %d : ", i);
       for (j = 0; j < 8; j++) {
            printf ("%d", bitarray[j]);
       }
}
}

//---------------------------------------------------------------------------

int *ByteToBinary (BYTE val)
/* Разбивает исходный Байт на биты. Возвращает массив из восьми элементов
   Каждый Nй элемент соответствует Nму биту.
   Принимает значения 1 или 0
*/
{           int *mass = new int[8];
            int t, i;
            for (t = 128, i = 0; t > 0; t /= 2, i++)
            {
                if ((val & t) != 0) mass[i] = 1;
                else if ((val & t) == 0) mass[i] = 0;
            }
  return mass;
}



Добавлено через 2 минуты и 59 секунд
Выдает сообщение об ошибке в строке № 65:

Cannot convert 'unsigned char *' to 'unsigned char'.
Type mismatch in parameter 'val' (wanted 'unsigned char', got 'unsigned char *')

Казалось бы, при чем тут char? smile  smile

Добавлено через 6 минут и 39 секунд
Цитата(feodorv @  14.4.2012,  14:11 Найти цитируемый пост)
Цитата(Shmell @  14.4.2012,  14:43 )
size_t count = FILE_SIZE/8;

Размер файла задаётся в байтах, а не в битах (это если деление на 8 задумано по этой причине)


count - это сколько байт необходимо считать. Мммм... Тут я запутался.... А ведь может быть нецелое количество байт в файле? Тогда как быть с остатком? Файл .txt. Да, в принципе, любой файл. Но в моем случае - файлы, связанные с текстом. Но не специфические изображения  - pdf, djvu!

Добавлено через 7 минут и 2 секунды
Считать надо весь файл.

Добавлено через 9 минут
Цитата(feodorv @  14.4.2012,  14:11 Найти цитируемый пост)
Почему sizeof(BYTE*)???


Но ведь я хочу байты считать. В массив. А потом уже каждый элемент массива конвертировать в двоичное представление. Что не так-то? Или я словосочетание "байт файла" воспринимаю буквально?

Добавлено через 13 минут и 43 секунды
Что же делать?
PM MAIL   Вверх
feodorv
Дата 14.4.2012, 15:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

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



По-шагам:
Цитата(Shmell @  14.4.2012,  15:31 Найти цитируемый пост)
if ((SecretFile = fopen ("c:\\test.txt", "r")) == NULL){
    cout<<"Could not to open file!!!"<<endl;
    cin.get();
  }

"r" надо заменить на "rb" всё таки)))
Если файл не удалось открыть, то SecretFile так и останется нуллом, а выполнение программы продолжится.... Будет "Программа выполнила недопустимую операцию..." Ну хотя бы return из main'а можно сделать при неудаче?


Цитата(Shmell @  14.4.2012,  15:31 Найти цитируемый пост)
if ((textbuf = (BYTE*) malloc(sizeof(BYTE*) * FILE_SIZE )) == NULL){

FILE_SIZE - это размер файла в байтах (да, нецелых байтов быть не может), поэтому и буфер нужен такого же размера:
Код

malloc(sizeof(BYTE) * FILE_SIZE ))

Но поскольку sizeof(BYTE) всегда 1, то можно просто:
Код

malloc(FILE_SIZE)

Кроме того, если уж произошёл такой крутой вираж в сторону C++, то malloc стоит заменить соответствующим new.


Цитата(Shmell @  14.4.2012,  15:31 Найти цитируемый пост)
   size_t count = FILE_SIZE/8;

То же самое: если нужен весь файл, то делить на 8 не нужно!!!! (Третий раз про это я писать не буду))))


Цитата(Shmell @  14.4.2012,  15:31 Найти цитируемый пост)
       bitarray = ByteToBinary (textbuf);

В подпрограмму ByteToBinary Вы отправляете указатель textbuf (то есть адрес на весь массив байт), а нужно лишь значение i-того байта:
Код

ByteToBinary (textbuf[i]);



Цитата(Shmell @  14.4.2012,  15:31 Найти цитируемый пост)
{           int *mass = new int[8];

Вы заказали память. Освобождать её где-нибудь собираетесь?
Вообще, при фиксированном и небольшом размере (в нашем случае - 8) заказ памяти можно заменить на стековую переменную:
Код

for (i = 0; i < count; i++) {
       int mass[8];
       ByteToBinary ( textbuf[i], mass);

Более того, как правильно заметил bsa, достаточно научиться битовым операциям и ненужны никакие дополнительные массивы))))

Это сообщение отредактировал(а) feodorv - 14.4.2012, 15:22


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
Shmell
Дата 14.4.2012, 15:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(feodorv @  14.4.2012,  15:07 Найти цитируемый пост)
Цитата(Shmell @  14.4.2012,  15:31 )
if ((textbuf = (BYTE*) malloc(sizeof(BYTE*) * FILE_SIZE )) == NULL){

FILE_SIZE - это размер файла в байтах (да, нецелых байтов быть не может), поэтому и буфер нужен такого же размера:


FILE_SIZE  объявлен как unsigned int. А буфер - это массив, по байту в каждом элементе. Что не так? Черт, сам не могу понять....

Добавлено через 1 минуту и 23 секунды
Цитата(feodorv @  14.4.2012,  15:07 Найти цитируемый пост)
Цитата(Shmell @  14.4.2012,  15:31 )
   size_t count = FILE_SIZE/8;

То же самое: если нужен весь файл, то делить на 8 не нужно!!!! (Третий раз про это я писать не буду))))


Т.е. делить не надо вообще ни на что?

Добавлено через 5 минут и 34 секунды
Цитата(feodorv @  14.4.2012,  15:07 Найти цитируемый пост)
В подпрограмму ByteToBinary Вы отправляете указатель textbuf (то есть адрес на весь массив байт), а нужно лишь значение i-того байта:
код C++
1:
ByteToBinary (textbuf[i]);



Вот это здорово! Как я сам не догадался.
PM MAIL   Вверх
KaZepKa
Дата 14.4.2012, 15:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



А вообще не проще будет открыть файловый поток (объект класса fstream)?
С++ всё таки )

Это сообщение отредактировал(а) KaZepKa - 14.4.2012, 15:40
PM MAIL   Вверх
Shmell
Дата 14.4.2012, 15:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(feodorv @  14.4.2012,  15:07 Найти цитируемый пост)
Более того, как правильно заметил bsa, достаточно научиться битовым операциям и ненужны никакие дополнительные массивы))))

Где про них можно почитать???




feodorv, Вы меня, пожалуйста извините, я просто уже почти неделю бодаюсь с задачей стенографического внедрения левого файла в картинку в формате TIFF. И вот из одной проблемы в другую меня кидает))

The BrainRush will never stopped!!! smile  smile  smile

Добавлено через 2 минуты и 50 секунд
Цитата(KaZepKa @  14.4.2012,  15:39 Найти цитируемый пост)
А вообще не проще будет открыть файловый поток (объект класса iofstream)?
С++ всё таки ) 

Сам не знаю, почему так сделал... В Visual Studio так работал с файлом. А здесь, месяц спустя начал тупить с fopen.
PM MAIL   Вверх
Shmell
Дата 14.4.2012, 16:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Была страница в интернете, где про fstream все было расписано, теперь не могу найти smile И нигде не могу найти)))) Везде какой-то бред))))
PM MAIL   Вверх
KaZepKa
Дата 14.4.2012, 16:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(Shmell @  14.4.2012,  17:00 Найти цитируемый пост)
Была страница в интернете, где про fstream все было расписано, теперь не могу найти  И нигде не могу найти)))) Везде какой-то бред)))) 

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

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

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

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

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


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

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


 




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


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

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