标题:如何读取二进制文件的内容,并转换?
只看楼主
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
得分:0 
你再看29楼

授人以渔,不授人以鱼。
2012-05-12 15:54
taohua300
Rank: 12Rank: 12Rank: 12
来 自:光
等 级:贵宾
威 望:14
帖 子:1636
专家分:3906
注 册:2009-3-11
得分:0 
以下是引用sh600839在2012-5-12 15:44:44的发言:


filetostr()在vfp5.0里没有,sh600004.day可以有几年的数据。

现在剩下4个字节浮点数怎么读出来?见二楼说明
?Ctobin(Substr(lcFileString,21,4),'4ns')

个性太多,无法显示
2012-05-12 15:58
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
得分:0 
浮点数的二进制格式转换比较麻烦,用C写来的快,我看这个数据本身也是用C写出来的。我可以用C写一个程序给你生成一个txt文件,你要怎样的格式?

授人以渔,不授人以鱼。
2012-05-12 16:01
taohua300
Rank: 12Rank: 12Rank: 12
来 自:光
等 级:贵宾
威 望:14
帖 子:1636
专家分:3906
注 册:2009-3-11
得分:0 
以下是引用sh600839在2012-5-12 15:52:35的发言:

是的,其中最大的那个是浮点数值,所以结果不对,应该是967万。
怎样读取浮点数啊????


附件是半年的资料。我一次读取32个字节,转换后写成txt文件,一直循环到文件尾就可以了。


我还是不明白:
fread()读取的值是字符型的,处理二进制数值肯定慢了。
我能不能直接从文件里读取成数值型(10进制或者16进制)????


tonydeng斑竹,你上面是用C语言编写的?用VFP行不行?
应该是34个字节吧
后面两个字节是回车和换行,可以不用处理

个性太多,无法显示
2012-05-12 16:01
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
得分:0 
这个是你30楼的数据转换后的txt文件:

sh600005.zip (7.64 KB)

授人以渔,不授人以鱼。
2012-05-12 16:12
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
得分:0 
以下是形成的可执行文件:
sh.zip (38.07 KB)


在vfp中用如下命令调用:
run sh sh600005

这里的参数sh600005不要给扩展名.day,程序默认使用.day作扩展名,然后用同样的名字给你生成sh600005.txt。我已设置了静态运行库编译,但不确定在你的机器上运行是否有缺dll提示,如果有,把信息贴上来,我上传相关dll即可。

附上相关代码:
程序代码:
#include <Windows.h>
#include <cstdio>

struct DATA
{
    int date;        // 日期
    int open;        // 开盘
    int max;        // 最高
    int min;        // 最低
    int close;        // 收盘
    float value;    // 成交金额   (这个是浮点数,怎么转换?)
    int quantity;    // 成交量
    int reserve;    // 保留
};

void wmain(int argc, wchar_t* argv[])
{
    if (argc < 2)
    {
        return;
    }

    wchar_t filename[MAX_PATH];

    DATA data;
    FILE* file1;
    FILE* file2;

    wcscpy_s(filename, argv[1]);
    wcscat_s(filename, L".day");
    if (_wfopen_s(&file1, filename, L"rb") == 0)
    {
        wcscpy_s(filename, argv[1]);
        wcscat_s(filename, L".txt");
        _wfopen_s(&file2, filename, L"wt");         // "wb"改为"wt"
        while (fread(&data, sizeof(data), 1, file1) > 0)
        {
            fwprintf_s(file2, L"日期:%d\n", data.date);
            fwprintf_s(file2, L"开盘:%d\n", data.open);
            fwprintf_s(file2, L"最高:%d\n", data.max);
            fwprintf_s(file2, L"最低:%d\n", data.min);
            fwprintf_s(file2, L"收盘:%d\n", data.close);
            fwprintf_s(file2, L"成交金额:%.4f\n", data.value);
            fwprintf_s(file2, L"成交量:%d\n\n", data.quantity);
        }
        fclose(file2);
        fclose(file1);
    }
}

修改一下代码,上面写错了,不应该是"wb",应用"wt",否则回车换行只有一个字节,而不是惯用的两个字节。exe文件没改。

[ 本帖最后由 TonyDeng 于 2012-5-12 22:28 编辑 ]

授人以渔,不授人以鱼。
2012-05-12 16:36
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
得分:0 
如果你的vfp5能用ctobin()函数,就可以直接用它来读取浮点数,帮助信息如下:



浮点数的二进制储存机制,是比较复杂微妙的,与机器、创建它的语言内部机制都有关,自己写算法解读它还原,不大现实,还原的数据有可能失真。通常,二进制文件,只使用整数结构的(日期、逻辑等都是整数结构),可以那样还原,但若涉及浮点数据,最好是原样怎么写下去就原样怎么读回来,避免偏差。这个二进制数据文件的格式,明显是用C类语言通过fwrite()写出来的,那么用C的fread()读回来,稳妥一些。

如果vfp5不支持ctobin()那样的用法,但又要出来浮点数,还是不要自己写的好,那等于自己写一个ctobin()函数了,里面还有点细节是我们未必了解的。

[ 本帖最后由 TonyDeng 于 2012-5-12 17:45 编辑 ]

授人以渔,不授人以鱼。
2012-05-12 17:00
sh600839
Rank: 2
等 级:论坛游民
帖 子:19
专家分:12
注 册:2005-8-30
得分:0 
谢谢大家的帮助,我的问题都得到解决了。
2012-05-14 17:11
andi2
Rank: 1
等 级:新手上路
帖 子:1
专家分:0
注 册:2020-6-6
得分:0 
function bytes_tolong
    para gcstring,start
    byte1=asc(substr(gcstring,start,1))
    byte2=asc(substr(gcstring,start+1,1))
    byte3=asc(substr(gcstring,start+2,1))
    byte4=asc(substr(gcstring,start+3,1))
    result = byte4*256*256*256 + byte3*256*256 + byte2*256 + byte1
return result

function bytes_tofloat
    para gcstring,start
    byte1=asc(substr(gcstring,start,1))
    byte2=asc(substr(gcstring,start+1,1))
    byte3=asc(substr(gcstring,start+2,1))
    byte4=asc(substr(gcstring,start+3,1))
    符号=1
    符号位=int(byte4/128)
    if 符号位=1
        符号=-1
    endif
    指数_整数=mod(byte4,128)*2+int(byte3/128)-127
    尾数小数=mod(byte3,128)*256*256 + byte2*256 + byte1
    指数_小数= -23
    result = 符号*(2^指数_整数 + 尾数小数 * 2^(指数_整数+指数_小数))
return result
2020-06-06 23:19



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-367387-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.043950 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved