Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 18.02.2011, 19:30   #1
Farrel
Форумчанин
 
Аватар для Farrel
 
Регистрация: 21.04.2010
Сообщений: 144
По умолчанию Работа с битовыми полями

Доброго времени суток! Я чего-то сольно затупил, и в нете не могу найти инфу. Собственно вопрос 1-й: как с помощью поля бит найти остаток от деления данного числа, к примеру на 2? И каким образом подгрузить из файла инфу в поле бит? (скажем загрузить из произвольного файла 1 байт?)
Я пробовал примерно так
Код:
f.read((char*)&field,8);
где f соответственно файловый поток, и field поле бит ()
Farrel вне форума Ответить с цитированием
Старый 18.02.2011, 20:56   #2
alex_x_x
Форумчанин
 
Регистрация: 31.01.2011
Сообщений: 160
По умолчанию

Farrel, размер всегда измеряется в байтах, поэтому
f.read((char*)&field,1);

Цитата:
Собственно вопрос 1-й: как с помощью поля бит найти остаток от деления данного числа
очевидно
Код:
char a = 15;
char mod = a & 1;
alex_x_x вне форума Ответить с цитированием
Старый 18.02.2011, 21:57   #3
Farrel
Форумчанин
 
Аватар для Farrel
 
Регистрация: 21.04.2010
Сообщений: 144
По умолчанию

Цитата:
Сообщение от alex_x_x Посмотреть сообщение
Farrel, размер всегда измеряется в байтах, поэтому
f.read((char*)&field,1);
а разве пишем не размер поля бит целиком?
Farrel вне форума Ответить с цитированием
Старый 18.02.2011, 22:17   #4
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

начнем с того вы не прочтете с файла один бит, поэтому считывать надо байтами(например всю структуру с вашими полями)
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 18.02.2011, 22:30   #5
Farrel
Форумчанин
 
Аватар для Farrel
 
Регистрация: 21.04.2010
Сообщений: 144
По умолчанию

ой, ошибся. В предыдущем посте я имел ввиду байт. Т.е.
Код:
f.read((char*)&field,8);
вместо проедложенного alex_x_x
Код:
f.read((char*)&field,1);
Конкретизируем проблему:
Код:
#include <iostream>
#include <fstream>
using namespace std;

struct field
{
	int i1:1;
	int i2:1;
	int i3:1;
	int i4:1;
	int i5:1;
	int i6:1;
	int i7:1;
	int i8:1;
	
};

class byte 
{
	field f;
public:
	byte()
	{
		f.i1=f.i2=f.i3=f.i4=f.i5=f.i6=f.i7=f.i8=0;
	}
};

void main()
{
	byte f;
	int i=3;
	fstream ff;
	ff.open("5.sh",ios::in | ios::out | ios::binary | ios::trunc);
	ff.write((char*)&i,sizeof(int));
	for(int j=0;j<4;j++)
		ff.read((char*)&f,sizeof(byte));
}
даже если не считать ошибки, вылетающей после выполнения кода(Run-Time Check Failure #2 - Stack around the variable 'f' was corrupted.), при попытке прочитать что-либо из файла, читается нечто непонятное (часть битов в поле заполняется -1)

Последний раз редактировалось Stilet; 19.02.2011 в 08:36.
Farrel вне форума Ответить с цитированием
Старый 19.02.2011, 01:33   #6
Dayman
Форумчанин
 
Аватар для Dayman
 
Регистрация: 12.01.2011
Сообщений: 186
По умолчанию

Код:
for(int j=0;j<4;j++)
ff.read((char*)&f,sizeof(byte));
С классами так не работают, либо читайте с помощью методов класса, либо делайте public field f; и читайте сразу туда (но зачем тогда класс? ваш конструктор можно заменить memset'ом), либо используйте union.
Lingua c++ non penis caninus est.
Dayman вне форума Ответить с цитированием
Старый 19.02.2011, 10:56   #7
Farrel
Форумчанин
 
Аватар для Farrel
 
Регистрация: 21.04.2010
Сообщений: 144
По умолчанию

Цитата:
Сообщение от Dayman Посмотреть сообщение
Код:
for(int j=0;j<4;j++)
ff.read((char*)&f,sizeof(byte));
С классами так не работают, либо читайте с помощью методов класса, либо делайте public field f; и читайте сразу туда (но зачем тогда класс? ваш конструктор можно заменить memset'ом), либо используйте union.
лан, согласен, затупил. Но дело в том, что изначально у меня была структура, а не класс, вот я и забыл исправить. Но дела это не меняет т.к. из файла всёравно читается (после того как поставил public битовому полю в классе) непонятно что, а именно всё те же -1.

PS
странно, но вижла не ругалась на попытки записать в private член класса инфу извне.
лан, поставим вопрос по-другому

Код:
#include <iostream>
#include <fstream>
using namespace std;

struct field
{
	int i1:1;
	int i2:1;
	int i3:1;
	int i4:1;
	int i5:1;
	int i6:1;
	int i7:1;
	int i8:1;
	
};

void main()
{
	field f;
	int i=3;
	fstream ff;
	ff.open("5.sh",ios::in | ios::out | ios::binary | ios::trunc);
	ff.write((char*)&i,sizeof(int));
	ff.read((char*)&f,sizeof(f));
}
в результате в field f оказывается несколько -1, в чём дело?
Farrel вне форума Ответить с цитированием
Старый 19.02.2011, 21:24   #8
Dayman
Форумчанин
 
Аватар для Dayman
 
Регистрация: 12.01.2011
Сообщений: 186
По умолчанию

Что надо исправить:
  1. битовые поля делайте unsigned
  2. после write сразу следует read; надо перенести указатель на начало файла, иначе непонятно, что вы читаете

Код:
#include <iostream>
#include <fstream>
using namespace std;

typedef union{
    int value;
    struct _bytes{
        unsigned int i1:1;
        unsigned int i2:1;
        unsigned int i3:1;
        unsigned int i4:1;
        unsigned int i5:1;
        unsigned int i6:1;
        unsigned int i7:1;
        unsigned int i8:1;
    } bytes;
} myByte;


void main()
{
    myByte f;
    int i=3;
    fstream ff;
    ff.open("5.sh",ios::in | ios::out | ios::binary | ios::trunc);
    ff.write((char*)&i,sizeof(int));
    ff.seekg(0);
    ff.read((char*)&f,sizeof(f));
    ff.close();
}
Lingua c++ non penis caninus est.
Dayman вне форума Ответить с цитированием
Старый 19.02.2011, 22:43   #9
Farrel
Форумчанин
 
Аватар для Farrel
 
Регистрация: 21.04.2010
Сообщений: 144
По умолчанию

Да, действительно, кажется пора поспать пару часов . Так оно действительно пашет.
И последний вопрос: как можно почитать файл в битовые структуры(независимо от его типа). Когда переписанный код твой я попробовал применить таким образом, в поле бит не записалось вообще ничего(trunc и запись в файл я естественно закоментил, файл я взял mp3). Я конечно понимаю, что в идеале необходимо знать структуру файла, но я себе такую роскошь позволить не могу, мне необходимо знать только как выглядит инфа в двоичном виде.

PS кстати файлик djvu почитать я всётаки смог, возможно таким образом читать можно толь пиратские форматы а вот лицензированные типа mp3 либо нельзя, либо с большими проблемами. И вот ещё что заметил, в djvu файле при чтении в написанной Dayman объединении при чтении часто меняется value причём значения она принимает самые разные, а вот данные в поле бит меняются гораздо реже, что подозрительно.

вот слегка поправленный мной код
Код:
#include <iostream>
#include <fstream>
using namespace std;

    struct _bytes{
        unsigned int i1:1;
        unsigned int i2:1;
        unsigned int i3:1;
        unsigned int i4:1;
        unsigned int i5:1;
        unsigned int i6:1;
        unsigned int i7:1;
        unsigned int i8:1;
    } bytes;



void main()
{
    _bytes f;
    int i=3;
    fstream ff;
    ff.open("1.djvu",ios::in | ios::out | ios::binary);
	if(!ff.is_open())
	{
		cout<<"error"<<endl;
		return;
	}
	cout<<sizeof(f)<<endl;
	system("pause");
	while(!ff.eof())
	{
		ff.read((char*)&f,1);
		cout<<f.i1<<f.i2<<f.i3<<f.i4<<f.i5<<f.i6<<f.i7<<f.i8<<endl;
	}
    ff.close();
}
после того, как в ff.read я заменил sizeof(f) на 1, дела пошли лучше и в поле бит стала появляться более адекватная информация.

Кажется дело во 2-м параметре ff.read sizeof(f) возвращает почему-то 4 хотя по идее в поле бит мы пишем только 1 байт. Я попытался изменить количесво бит в поле, но sizeof всё так же возвращает 4. Кто нить может объяснить сей факт?

Последний раз редактировалось Farrel; 19.02.2011 в 23:42.
Farrel вне форума Ответить с цитированием
Старый 19.02.2011, 23:50   #10
Dayman
Форумчанин
 
Аватар для Dayman
 
Регистрация: 12.01.2011
Сообщений: 186
По умолчанию

Поправлю свой пример (поэтому и возвращал sizeof 4 байта)
Вместо
Код:
typedef union{
    int value;
должно быть
Код:
typedef union{
    unsigned char value;
Lingua c++ non penis caninus est.
Dayman вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Проблема с битовыми операциями sid Помощь студентам 4 05.12.2010 23:01
Interbase. Работа с BLOB-полями Sewell БД в Delphi 5 25.11.2010 08:46
параметрическое открытие OpenForm, работа с полями таблицы через .Fields Познающий Microsoft Office Access 10 16.06.2010 01:50
Программная работа с полями (формула) NomadV Microsoft Office Word 7 08.04.2010 15:21
БД Access и операции с полями WishNight БД в Delphi 3 05.04.2010 13:00