注册 登录
编程论坛 VC++/MFC

hzk16文件无法读取

kaitianjian 发布于 2012-02-27 15:03, 1161 次点击
最近在用mfc写一个点阵取模程序,但是hzk16文件无法读取,而.txt文件都能读取?

void CMSComDlg::ReadDataFromFile()
{
    CFile file("HZK16", CFile::modeRead|CFile::typeBinary);
    memset(cBuf, 0, 1024);
    file.Read(cBuf, 32);
    file.Close();
    Invalidate();
}
22 回复
#2
mayuebo2012-02-28 08:10
Buffer太小了吧
#3
kaitianjian2012-02-28 12:52
应该不小,估计是数据格式有问题
从书上了解到,串口控件mscom的setoutput函数发送二进制数据时,要将
字节型数据存入参数变量中。

void CMSComDlg::OnSend()
{
    UpdateData();   //更新数数据参数

   ReadDataFromFile();
   m_strSendData.Format("%s", cBuf);
    _variant_t vSendData;   //定义发送数据变量
    vSendData = m_strSendData;  //转换发送数据类型

     m_ctrMSCom.SetOutput(vSendData);//发送数据
#4
TonyDeng2012-02-28 13:04
你說的無法讀取是什麼情形?
#5
kaitianjian2012-02-28 19:40
今天又试了一下,改用串口类 CSerialPort.cpp,貌似可以读到数据,但只能读到一个,而且发送时没见反应


void CSerialPortComDlg::ReadDataFromFile()   //读文本数据
{
CFile file("HZK16", CFile::modeRead|CFile::typeBinary);
//    char *p = m_strSendData.GetBuffer(m_strSendData.GetLength());
    memset(cBuf, 0, 1024);
//    file.Seek(100,CFile::begin);  
    file.Read(cBuf, 32);   
    file.Close();
    Invalidate();
}

void CSerialPortComDlg::OnSend()
{
    // TODO: Add your control notification handler code here
    UpdateData();
    ReadDataFromFile();
       int i = 0;
    while(cBuf[i++])
    assert(i=1);     //貌似cBuf里只有一个元素
    m_spSerialPort.WriteToPort(cBuf);
  //  m_spSerialPort.WriteToPort((char *)(LPCTSTR)m_strSendData);
}
 
我把整个程序贴出来,里面有具体的说明
只有本站会员才能查看附件,请 登录

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

只有本站会员才能查看附件,请 登录
#6
TonyDeng2012-02-28 19:49
你的代碼就只讀了hzk16中的32byte數據,即全角空格。是不是想把整個字庫傳送出去呀?不需要的呀,要哪個字就送那個字的32byte字模,不用全部送過去的,除非你這個是初始化階段,不怕耗時。
#7
kaitianjian2012-02-29 10:21
32B全角空格,我不太明白?
我现在只是在测试,看能否读出32b的数据并发送出去!
#8
TonyDeng2012-02-29 12:40
hzk16是16*16點陣的字模數據庫,每32byte一個字,是按照區位碼順序排列的。第一個32Byte數據是全0的,對應全角漢字空格(區位碼0101,空格是什麼都沒有的,所以對應的點陣全滅,即全部是0,可能這樣你就以為沒讀到數據),0102是頓號……要提取某個漢字的字模,用內碼計算出區位碼,然後定位到文件的正確位置,取出32Byte數據就是了。其實你只是要測試串口通訊的話,不用拿hzk16做數據,隨便寫若干字節就可以了。
#9
kaitianjian2012-03-01 13:30
恩,我再看看,如果不行,就用fread()试试!
#10
kaitianjian2012-03-03 10:54
改用了fread和fseek函数,直接将c语言读取自摸程序中的一段代码靠过来,却出现有得字能读完整出,如我、他,有得字只能读取一点或读不到,如“你”只能读到一个“▲“字符,纳闷啊?

void CSerialPortComDlg::ReadDataFromFile()
{   
     unsigned  char i=0xa1,j=0xa1;
     unsigned   char   qh,wh;
     unsigned  long offset;
     char *p = m_strSendData.GetBuffer(m_strSendData.GetLength());//获得汉字区位码所在指针
     unsigned   char q = p[0], w = p[1];
     qh=q-0xa0;
     wh=w-0xa0;
     offset=((qh-1)*94+(wh-1))*32L;  //计算在自摸中偏移量
     FILE *fd;
     fd=fopen( "HZK16 ", "rb ");
     fseek(fd,offset,SEEK_SET);
     memset(cBuf, 0, 1024);
     fread(cBuf,32,1,fd);   
     fclose(fd);

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

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

只有本站会员才能查看附件,请 登录
#11
kaitianjian2012-03-03 10:57
这是c语言中的代码,跟上面的读取代码一样,却都能完整读出

只有本站会员才能查看附件,请 登录
#12
TonyDeng2012-03-03 13:02
这样吧,你帮我一下,你替我找一下hzk16 all全套字库,能够下载的,我替你写这个读字模的函数。
#13
kaitianjian2012-03-03 13:56
好~
只有本站会员才能查看附件,请 登录
#14
TonyDeng2012-03-03 13:59
好,正在下载。
#15
TonyDeng2012-03-03 18:04
验证过,你原先的代码读取字模的那部分是正确的。问题估计出在你那个p字符串上,其中夹杂了非汉字,造成了乱码。普通ASCII字符的字模不在hzk16中的,你把那些字符筛选出来特殊处理,用全部都是汉字的字符串测试一下看。
#16
kaitianjian2012-03-03 19:44
我还是用一个一个的汉字测试的,有得字可以,有得字不行!
上面的“c语言文件”中所用的函数跟那个一样,但就没问题!
是不是编码有问题,MFC默认是Unicode的吗?
#17
TonyDeng2012-03-03 20:16
是的,hzk16是GB2312编码的字库,你如果要直接用汉字检字,就必须把汉字内码转化为GB2312编码,要么你另做一个检字表,直接用区位码提取字模。
#18
TonyDeng2012-03-03 22:52
你能找到这个转换表么?如果没有,只能自己想办法做了。我也没有。
#19
TonyDeng2012-03-04 04:55
我给你做了一个编码转换表,附上源代码,你看一看能不能用:

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


注:如果你不用vector容器,就把它改成数组,一次fread()把整个文件读进来。编码表记录数为7445,定死了也没关系,这个数不会变的。

[ 本帖最后由 TonyDeng 于 2012-3-4 05:11 编辑 ]
#20
TonyDeng2012-03-04 12:16
不好意思,忘了给源代码,这个才是
只有本站会员才能查看附件,请 登录
#21
kaitianjian2012-03-04 14:36
我用内码减去a0可以取到字模,但是发送有问题,
然后我将取到的每一字节字模都加上a1,貌似可以发送了!
#22
TonyDeng2012-03-04 14:46
简体中文Windows系统使用936代码页,汉字编码与GB2312是没有对应关系的,没有算法,只能查表。除非你能够把自己Windows系统设置成GB2312编码的。
#23
kaitianjian2012-03-05 09:42
恩,改用了mscom控件!
按照mscom控件的setoutput函数说明,当发送二进制数据时,要将字节型数据存入参数变量中,
于是从网上搜了下,改成了下面的程序进行了转换:
可以将输入的汉字读取字模并全部发送,不过还需验证!

COleVariant vSendData2;
   CByteArray OutBuf;
  OutBuf.SetSize(m_strSendData.GetLength()*32);//设置大小
   int i;
  for(i = 0; i < m_strSendData.GetLength()*32; i++)
   OutBuf[i] = cBuf[i]; //转换类型
 vSendData2 = OutBuf; //转换发送数据类型
   m_ctrMSCom.SetOutput(vSendData2);//发送数据
1