请教关于固定格式文本文件操作问题!!!(升序排列)在线急等!!!!(200分)

  • 主题发起人 主题发起人 vclsaga
  • 开始时间 开始时间
V

vclsaga

Unregistered / Unconfirmed
GUEST, unregistred user!
请教各位高手,现有固定格式文件文件例:
123345 姓名 22
234234 年龄 23
828232 姓名 33
第一个字段长度为10;
第二个字段长度为10;
第三个字段长度为2;
我想插入第四条记录
125555 年龄 44
插入后的记录为
123345 姓名 22
125555 年龄 44
234234 年龄 23
828232 姓名 33
按第一字段进行排序,我想用折半插入方法,可是不知道怎么实现?
请教各位高手,如何实现!!!???
注:用PASCAL实现,不用DELPHI,是DOS下编程实现!!!!
 
幫你頂下
 
用数组,将此文本文件的内容分别赋给数组,然后进行插入排序,仅供参考.
 
delphi天堂群:4654765,不去是你的损失
 
放入数组是一个办法,
也可以把3个字段当作一个对象放入list啥的,
放入数据库排序也是很方便的
 
只能Pascal?
这明显是数据结构的考题嘛.嘿嘿
让你上班不听讲....
 
能不能不用数组啊!我的程序主要用在数据采集器里,用的是仿DOS操作系统,内存有限啊!!!!!拜拜各位了!!!!
 
不知楼主是问排序的问题还是文本插入的问题?
排序的问题我没兴趣,不知您究竟是在问哪一个?
 
文本插入问题!!!
将新的内容按升序插入到文件中!!!!
谢谢 !!!!
 
专门在 弄个索引文件 就好...排序什么的 都在索引里面做..
 
你以前的文件是排序好的吗?如果是的话.可以先便历一下,找到位置,然后再把你的数据插入进去.
 
文件内容是排序的,升序排序!!!!!
 
告诉你一个偷懒的做法,用TStringList
LoadFromFile 调入;
Sort 排序
Add 增加数据
SaveToFile 保存。
这里面,保存之前或者使用之前调用一次 Sort 排序,TStringList这个类会为你排序的。
如果你想自己排序,那么,参考一下TStringList的排序函数就可以自己写了。
 
谢谢楼上哥们,这个方法我也知道,但是要在PASCAL7.0下写程序,而且程序是在DOS下运行的,所以TSTRINGLIST是无法使用的!
我有个想法是用折半插入,但是不知道该如何定位,比如如下记录:
12345
12346
12348
12349
我要插入一条记录:12347
怎么样知道12347应该在第三行写入,结果应为
12345
12346
12347
12348
12349
谢谢各位了!!!
 
自己再顶一下!!!!!
 
1. 既然是程序员, 这种简单的检索定位应该是自己很容易做到的;
2. TStringList很简单类, 自己写一个都可以; 更简单的办法就是直接移植Delphi中的类到BP7中也可以;
3. BP7(或者TP7)中本来就有TStringList(或者TStringCollection)的, 基本一样; //在objects单元中;
4. 还能在DOS下用pascal编程, 很不错; 顺便告诉你一个我常用的东西:
context代码编辑器 // 可以在Windows下编写、编译DOS系统下的tp(bp)程序;
 
To 楼主:
1、有点空闲给你写了一段程序,用 Delphi 控制台程序编译,纯 Pascal。之所以没用 TP7 编译,一是我手头没有 TP7,二是解决问题必须要用到 BlockRead、BlockWrite 函数,用于精确控制读取、写入文件的字节数,而在 TP7 中这两个函数严格针对无类型文件,而我的程序又必须要设定文件以字节为单位(file of Byte),所以在 TP7 中无法发挥这两个函数的作用,Delphi 编译环境则不存在这个问题。
2、程序如下,有点小长:
program Project1;

{$APPTYPE CONSOLE}

//StrLCopy 在 SysUtils 单元,原样抄过来,一是为了减小文件大小,而是避免间接引用 Windows 单元
function StrLCopy(Dest: PChar; const Source: PChar; MaxLen: Cardinal): PChar; assembler;
asm
PUSH EDI
PUSH ESI
PUSH EBX
MOV ESI,EAX
MOV EDI,EDX
MOV EBX,ECX
XOR AL,AL
TEST ECX,ECX
JZ @@1
REPNE SCASB
JNE @@1
INC ECX
@@1: SUB EBX,ECX
MOV EDI,ESI
MOV ESI,EDX
MOV EDX,EDI
MOV ECX,EBX
SHR ECX,2
REP MOVSD
MOV ECX,EBX
AND ECX,3
REP MOVSB
STOSB
MOV EAX,EDX
POP EBX
POP ESI
POP EDI
end;

procedure InsertRecord(FileName, RecordStr: string);
const
INDEX_LEN = 10;
RECORD_SIZE = 10 + 10 + 2 + 2;
var
f: file of Byte;
iFileSize, iBufSize, i, r, lo, hi, mid: Longint;
buf: PChar;

function GetRecordIndex(RecNo: Longint): Longint;
begin
Result := 0;
if RecNo < 1 then Exit;
FillChar(buf^, INDEX_LEN + 1, 0);
Seek(f, (RecNo - 1)*RECORD_SIZE);
BlockRead(f, buf^, INDEX_LEN);
Val(buf, Result, i);
end;

begin
AssignFile(f, FileName);
Reset(f);
iFileSize := FileSize(f);
i := iFileSize mod RECORD_SIZE;
if i <> 0 then
begin
Seek(f, iFileSize);
BlockWrite(f, #13#10, 2);
Inc(iFileSize, RECORD_SIZE - i);
end;

//用折半查找插入点,存储于变量 lo 中
GetMem(buf, INDEX_LEN + 1);
FillChar(buf^, INDEX_LEN + 1, 0);
StrLCopy(buf, PChar(RecordStr), INDEX_LEN);
Val(buf, r, i);
lo := 1;
hi := iFileSize div RECORD_SIZE;
if r >= GetRecordIndex(hi) then
lo := hi + 1
else if r >= GetRecordIndex(lo) then
begin
while lo <= hi do
begin
mid := (lo + hi) div 2;
if r < GetRecordIndex(mid) then
hi := mid - 1
else lo := mid + 1;
end;
end;
FreeMem(buf);
lo := (lo - 1)*RECORD_SIZE;

//把新纪录插入到相应位置
iBufSize := iFileSize - lo + RECORD_SIZE;
GetMem(buf, iBufSize);
FillChar(buf^, RECORD_SIZE - 2, 0);
StrLCopy(buf, PChar(RecordStr), RECORD_SIZE - 2);
Move(#13#10, buf[RECORD_SIZE - 2], 2);
Seek(f, lo);
BlockRead(f, buf[RECORD_SIZE], iBufSize - RECORD_SIZE);
Seek(f, lo);
BlockWrite(f, buf^, iBufSize);
FreeMem(buf);

Close(f);
end;

begin
InsertRecord('d:/a.txt', '100000 大便 00');
end.
3、至于其他仁兄建议的 TStringList 您也可以试一试。不过我写的应该是最基本的代码,我对类不类的一向不感兴趣,程序能用就结贴,不能用也说一声,好吧?
 
坐下来,,学习学习
 
1、补充一句,控制台程序不能在纯 dos 下运行,不知楼主的环境是否是 32 位的;如果是 16 位的可以用 Delphi for DOS 重新编译一下。
2、TP 提供的文件读写函数极其操蛋!BlockRead、BlockWrite、Read、Write 等等对精确控制读、写字节数十分恶心,BlockWrite 要求事先声明缓冲区的大小,否则默认按 128 处理,就是说一开始就要给出缓冲区的类型,换句话说用 GetMem 动态生成缓冲区根本不可能。我预先知道缓冲区有多大还他妈的用你 TP 干嘛?
 
非常感谢各位的帮助!!!!
学习了!!!再谢谢!!!!
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
I
回复
0
查看
601
import
I
I
回复
0
查看
770
import
I
D
回复
0
查看
1K
DelphiTeacher的专栏
D
后退
顶部