注册 登录
编程论坛 VFP论坛

VFP封装结构类型示例(四) [结]

吹水佬 发布于 2022-03-30 21:07, 3105 次点击
VFP封装结构类型,作为示例最后探讨一下数据结构与链表。
VFP 的 DBF 也是应用数据结构与链表的产物,学VFP的对这方面了解一下可以加深对 DBF 的理解,也可以设计其他格式的数据文件。
相关文件
只有本站会员才能查看附件,请 登录

程序代码:

CLEAR
cDefPath = ADDBS(JUSTPATH(SYS(16)))
SET DEFAULT TO (cDefPath)

#INCLUDE apiFuns.h
SET PROCEDURE TO apiFuns.prg, StructClass.prg ADDITIVE
LoadApi()

ds = CREATEOBJECT("数据结构")
ds.create()
dt = CREATEOBJECT("数据表")

bufSize = ds.size
pBuffer = myMalloc(bufSize)

head = 0    && 头记录指针
last = 0    && 尾记录指针

filename = cDefPath + "test.dat"
load_data(filename)
add_data("张三", 1, 18, 170)
add_data("李四", 2, 22, 175)
list_data()
save_data(filename)

SET PROCEDURE TO
CLEAR ALL
RETURN

DEFINE CLASS 数据结构 as STRUCT_CLASS
    PROCEDURE init
        this.stInit("name", "C",10)
        this.stInit("num1", "U",1)
        this.stInit("num2", "I",2)
        this.stInit("num3", "I",4)
    ENDPROC
ENDDEFINE

DEFINE CLASS 数据表 as STRUCT_CLASS
    PROCEDURE init(ds)
        this.stInit("数据记录", "C",17)
        this.stInit("next",     "U",4)
    ENDPROC
ENDDEFINE

FUNCTION add_data(name, num1, num2, num3)
    LOCAL ptr
    ptr = dt.create()
    ds.setValue("name", name, ptr)
    ds.setValue("num1", num1, ptr)
    ds.setValue("num2", num2, ptr)
    ds.setValue("num3", num3, ptr)
    dt.setValue("next", 0,    ptr)
    IF last != 0
        dt.setValue("next", ptr,  last)
    ENDIF
    IF head == 0
        head = ptr
    ENDIF   
    last = ptr
    RETURN last
ENDFUNC

FUNCTION load_data(filename)
    IF !FILE(filename)
        RETURN 0
    ENDIF
    LOCAL fp, ptr
    fp = myFOpen(filename, "rb")
    IF  fp == 0
        RETURN 0
    ENDIF
    head = 0
    last = 0
    IF apiFRead(pBuffer,bufSize,1,fp) == 1
        head = dt.create()
        apiMemcpy_s(head, bufSize, pBuffer, bufSize)
        dt.setValue("next", 0, head)
        last = head
    ENDIF
    DO WHILE apiFRead(pBuffer,bufSize,1,fp) == 1
        ptr = dt.create()
        apiMemcpy_s(ptr, bufSize, pBuffer, bufSize)
        dt.setValue("next", 0, ptr)
        dt.setValue("next", ptr, last)
        last = ptr
    ENDDO
    apiFClose(fp)
    RETURN head
ENDFUNC

FUNCTION save_data(filename)
    LOCAL fp, ptr
    fp = myFOpen(filename, "wb")
    IF  fp == 0
        RETURN 0
    ENDIF
    ptr = head
    DO WHILE ptr != 0
        apiFWrite(ptr, bufSize, 1, fp)
        ptr = dt.getValue("next", ptr)
    ENDDO
    apiFClose(fp)
    RETURN 1
ENDFUNC

FUNCTION list_data()
    LOCAL ptr
    ptr = head
    DO WHILE ptr != 0
        ?  ds.getValue("name", ptr)
        ?? ds.getValue("num1", ptr)
        ?? ds.getValue("num2", ptr)
        ?? ds.getValue("num3", ptr)
        ptr = dt.getValue("next", ptr)
    ENDDO
ENDFUNC

17 回复
#2
sdta2022-03-30 22:11
谢谢吹版,收藏了!
#3
nbwww2022-03-31 06:21
收藏学习
#4
schtg2022-03-31 07:17
吹版,谢谢!
#5
easyppt2022-03-31 10:07
谢谢 吹版!
#6
吹水佬2022-03-31 10:19
增加浮点数类型
只有本站会员才能查看附件,请 登录

只有本站会员才能查看附件,请 登录

程序代码:

CLEAR
cDefPath = ADDBS(JUSTPATH(SYS(16)))
SET DEFAULT TO (cDefPath)

#INCLUDE apiFuns.h
SET PROCEDURE TO apiFuns.prg, StructClass.prg ADDITIVE
LoadApi()

ds = CREATEOBJECT("数据结构")
ds.create()
dt = CREATEOBJECT("数据表")

bufSize = ds.size
pBuffer = myMalloc(bufSize)

head = 0    && 头记录指针
last = 0    && 尾记录指针

filename = cDefPath + "test.dat"
load_data(filename)
add_data("三姑", 1, 18, 170,     1.1, -1.1)
add_data("六婆", 2, 22, 175,  -22.22, 22.22)
add_data("七婶", 3, 36, 180, 333.333, -333.333)
list_data()
save_data(filename)

SET PROCEDURE TO
CLEAR ALL
RETURN

DEFINE CLASS 数据结构 as STRUCT_CLASS
    PROCEDURE init
        this.stInit("name", "C",10)    && 字符串
        this.stInit("num1", "U",1)     && 无符号整数
        this.stInit("num2", "I",2)     && 有符号整数
        this.stInit("num3", "I",4)
        this.stInit("num4", "F",4)     && 单精度浮点数
        this.stInit("num5", "F",8)     && 双精度浮点数
    ENDPROC
ENDDEFINE

DEFINE CLASS 数据表 as STRUCT_CLASS
    PROCEDURE init(ds)
        this.stInit("数据记录", "C",29)
        this.stInit("next",     "U",4)
    ENDPROC
ENDDEFINE

FUNCTION add_data(name, num1, num2, num3, num4, num5)
    LOCAL ptr
    ptr = dt.create()
    ds.setValue("name", name, ptr)
    ds.setValue("num1", num1, ptr)
    ds.setValue("num2", num2, ptr)
    ds.setValue("num3", num3, ptr)
    ds.setValue("num4", num4, ptr)
    ds.setValue("num5", num5, ptr)
    dt.setValue("next", 0,    ptr)
    IF last != 0
        dt.setValue("next", ptr,  last)
    ENDIF
    IF head == 0
        head = ptr
    ENDIF   
    last = ptr
    RETURN last
ENDFUNC

FUNCTION load_data(filename)
    IF !FILE(filename)
        RETURN 0
    ENDIF
    LOCAL fp, ptr
    fp = myFOpen(filename, "rb")
    IF  fp == 0
        RETURN 0
    ENDIF
    head = 0
    last = 0
    IF apiFRead(pBuffer,bufSize,1,fp) == 1
        head = dt.create()
        apiMemcpy_s(head, bufSize, pBuffer, bufSize)
        dt.setValue("next", 0, head)
        last = head
    ENDIF
    DO WHILE apiFRead(pBuffer,bufSize,1,fp) == 1
        ptr = dt.create()
        apiMemcpy_s(ptr, bufSize, pBuffer, bufSize)
        dt.setValue("next", 0, ptr)
        dt.setValue("next", ptr, last)
        last = ptr
    ENDDO
    apiFClose(fp)
    RETURN head
ENDFUNC

FUNCTION save_data(filename)
    LOCAL fp, ptr
    fp = myFOpen(filename, "wb")
    IF  fp == 0
        RETURN 0
    ENDIF
    ptr = head
    DO WHILE ptr != 0
        apiFWrite(ptr, bufSize, 1, fp)
        ptr = dt.getValue("next", ptr)
    ENDDO
    apiFClose(fp)
    RETURN 1
ENDFUNC

FUNCTION list_data()
    LOCAL ptr
    ?  ds.aSTRUCT[1,1] + "  "
    ?? ds.aSTRUCT[2,1] + "     "
    ?? ds.aSTRUCT[3,1] + "     "
    ?? ds.aSTRUCT[4,1] + "               "
    ?? ds.aSTRUCT[5,1] + "                 "
    ?? ds.aSTRUCT[6,1]
    ptr = head
    DO WHILE ptr != 0
        ?  ds.getValue("name", ptr)
        ?? ds.getValue("num1", ptr)
        ?? ds.getValue("num2", ptr)
        ?? ds.getValue("num3", ptr)
        ?? ROUND(ds.getValue("num4", ptr), 4)
        ?? ROUND(ds.getValue("num5", ptr), 4)
        ptr = dt.getValue("next", ptr)
    ENDDO
ENDFUNC
#7
aqyejun2022-03-31 14:41
谢谢分享
#8
schtg2022-04-01 06:27
谢谢吹版!
#9
吹水佬2022-04-02 20:36
修改了一下
原用数组来保存分配的结构块内存地址,这样会受到数组最大数目的限制。
现改用地址链表来保存分配的内存地址,这样只会受可用内存大小的限制。


[此贴子已经被作者于2022-4-4 14:44编辑过]

#10
schtg2022-04-03 05:39
@吹版,辛苦啦,谢谢!
#11
吹水佬2022-04-04 14:46
回复 9楼 吹水佬
只有本站会员才能查看附件,请 登录
#12
schtg2022-04-05 05:52
@吹版,谢谢!
#13
sam_jiang2022-04-05 13:55
版主功力深厚,好奇是做什么工做的?
#14
吹水佬2022-04-05 15:01
以下是引用sam_jiang在2022-4-5 13:55:09的发言:

版主功力深厚,好奇是做什么工做的?

功力深厚就太过奖啦,花拳绣腿还切实点。
专职与写程序无关,这是过去的事。现在没工作了,来这学习吹吹水好打发一下时间。
门道内,明眼人一看就清楚,本人学生一个。如果有认真关注本人写的东东,很多都是急用先学,边学边写,边写边改。
写程序纯属个人业余爱好,总喜欢写点小程序来实现一些类似大软件的某个功能,作为自己玩电脑的小工具。
#15
丁春秋yxp2022-04-06 21:30
回复 14楼 吹水佬
吹版主人才啊,我从dBASE Ⅲ开始,大大小小写了几十个系统(能实现某个功能,我就称为系统),什么人事管理啊、年度积分考核啊、工资管理啊、收租管理啊、抽签啊之类,在单位也被领导同事刮目相看。
最重要的,对SQL我是一窍不通,更不用说看明白吹版主的程序了。
#16
qq888811112022-04-11 13:31
不错
#17
myjut2022-04-27 15:25
不简单!
#18
myjut2022-04-27 15:29
dBASE Ⅲ,FoxBase,FoxPro,VFP 版主有功底
1