如何用一次读写操作实现多个布尔变量的读写操作(30分)

  • 主题发起人 主题发起人 soso
  • 开始时间 开始时间
S

soso

Unregistered / Unconfirmed
GUEST, unregistred user!
请教各位高手一个非常简单的问题:
如何用一次读写操作实现多个布尔变量的读写操作?

如:b1,b2,b3,...,bn : Boolean;

需要用文件来保存它们,如何同过位操作或其他方式,只进行一次读写即可实现它们的存取??

如列出源码,30分全部送出,快来抢呀!!

 
定义一个字符串:boolstring:string[n];

如果bi为false 那么boolstring:=0;
否则 boolstring:=1;

每次只要存取这一字符串,就可通过对应的值得到你要的结果.

 
那是不是太烦琐了,而且读取时不方便,我记得用 and , or 即可实现此功能。不知那位大虾知道详解
 
把这些boolean放在数组里面进行操作:

写文件:
var f:file;
ary:array[0..9] of boolean;
i:integer;
begin
for i:=0 to 9 do ary:=true;

assignfile(f,'c:/test.dat');
rewrite(f,1);
blockwrite(f,ary[0],sizeof(ary));
closefile(f);
end;

读文件:
var f:file;
ary:array[0..9] of boolean;
i:integer;
begin
assignfile(f,'c:/test.dat');
reset(f,1);
blockread(f,ary[0],sizeof(ary));
closefile(f);
end;
 


function EncodeBools(bools : array of Boolean) : Integer;
var
i: Integer;
b : Boolean;
begin
Assert(High(bools) - Low(bools) <=32);
Result := 0;
for i := Low(bools) to High(bools) do
begin
b := bools;
Result := Result or (Integer(b) shl i);
end;
end;

function DecodeBools(Value : Integer
Index : Integer) : Boolean;
begin
Assert(Index < 32);
Result := Boolean((Value and (1 shl Index)) shr Index);
end;

procedure ShowBoolValue(b : Boolean);
begin
if b then ShowMessage('True') else ShowMessage('False');
end;

procedure TForm1.BitBtn1Click(Sender: TObject);
var
b1, b2, b3, b4, b5 : Boolean;
b6, b7, b8, b9, b10 : Boolean;
BoolsValue : Integer;
begin
b1 := False;
b2 := False;
b3 := True;
b4 := False;
b5 := True;
BoolsValue := EncodeBools([b1, b2, b3, b4, b5]);
//ShowMessage(IntToStr(BoolsValue));
b6 := DecodeBools(BoolsValue, 0);
b7 := DecodeBools(BoolsValue, 1);
b8 := DecodeBools(BoolsValue, 2);
b9 := DecodeBools(BoolsValue, 3);
b10 := DecodeBools(BoolsValue, 4);
ShowBoolValue(b6);
ShowBoolValue(b7);
ShowBoolValue(b8);
ShowBoolValue(b9);
ShowBoolValue(b10);
end;
 
非常感谢三位大虾的指点,特别是smartkid和cakk,稍后分钱,希望有更多的人讨论,或许有更easy的点子。
 
smartkid:居然用到了assert! 够严谨了. :-)大侠风范
 
var
ary:array[0..9] of boolean;

FillChar(ary,SizeOf(ary),1);//全体True
FillChar(ary,SizeOf(ary),0);//False
 
如果是想一次写到文件中, 而且变量数目已知, 可以用:

var f: file of boolean;b1, b2, b3:boolean;
begin
b1:=false;
b2:=true;
b3:=true;

assignfile(f, 'c:/aaa');
rewrite(f);
write(f, b1, b2, b3);
closefile(f);

end;
读也是类似的:
assignfile(f, 'c:/aaa');
reset(f);

read(f, b1, b2, b3);
closefile(f);

一个变量一个字节, 空间稍浪费了一些.

此外, 可以利用open parameters的方法,
类似于自己实现write/read函数. 每8个变量合成一个字节.
 
我的方法就是一个变量一个字节,而且不限数量.

用位操作当然也可以实现,但是转换起来很麻烦,不一定省事.
 
>>够严谨了. :-)大侠风范

马屁!
他的程序可以改进:

function EncodeBools(bools : array of Boolean):<font size=red>Int64</font>;
var
I:Integer;
begin
Assert(High(Bools)-Low(Bools)<=<font size=red>SizeOf(Result)*8</font>)

Result:=0;
for I:=Low(Bools) to High(bools) do
<font size=red>if Bools then
Result:=Result or (1 shl (I-Low(Bools))</font>;
end;

我更倾向于IKnow的方法,
cAkk的方法还要先保存到数组,麻烦!
 
Ikonw的方法如果变量数目少还可以,如果有100个变量呢?
 
还是我的方法最省事。
 
hexi: 人家问的是"需要用<font color=red>文件</font>来保存它们,如何同过位操作或其他方式,只进行一次读写即可实现它们的存取??"
 
呵呵, 蚯蚓看来很是忿不平呀:-)
 
不好意思
本来要写&amp;lt;font color=red&amp;gt;
结果写成了&amp;lt;font size=red&amp;gt;
于是就成了上面那种怪怪的效果
 
用无类型参数的方式再写一个简单的DecodeBools(不过不如上一种安全):

procedure DecodeBools(const bools : array of const
Value : Integer);
type
PBoolean = ^Boolean;
var
i : Integer;
p : PBoolean;
begin
for i := 0 to High(bools) do
begin
Assert(bools.VType = vtPointer);
p := bools.VPointer;
p^ := Boolean((Value and (1 shl i)) shr i);
end;
end;


调用时的方法用:

DecodeBools([@b6, @b7, @b8, @b9, @b10], BoolsValue);

 
with TFileStream.Create('HaHa.Dat', fmCreate) do Write(ary[0],Sizeof(ary));//写
with TFileStream.Create('HaHa.Dat', fmOpenRead) do Read(ary[0],Sizeof(ary));//读


 
with TFileStream.Create('HaHa.Dat', fmCreate) do
begin
Write(ary[0],Sizeof(ary));//写
Free
end;

with TFileStream.Create('HaHa.Dat', fmOpenRead) do
begin
Read(ary[0],Sizeof(ary));//读
Free
end;

 
后退
顶部