关于自定义struct中数据的读写问题

voice1122 2010-08-30 04:33:34
问题:要对一个文件中的数据进行读操作,然后写入对应的数据表中。已知文件中的数据都是以一定的数据结构存在的,于是定义了一个结构struct tt{char s1[5];char s2[5];char s3[30];};来读取。采用read(file,&tt,length)读取数据后,在对tt中的数据每个字段进行操作时发现,取tt.s1的时候会把整个tt的数据都显示出来。如何操作可以实现每次取的值正好是s1,s2,s3的值。谢谢
...全文
142 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
voice1122 2010-09-03
  • 打赏
  • 举报
回复
最初定的分太少,所以能分的也少了。
实在抱歉!
voice1122 2010-09-03
  • 打赏
  • 举报
回复
看来只能先这样了。
先结贴了。欢迎大家讨论,看有没有更自然的办法
zzbinfo 2010-09-03
  • 打赏
  • 举报
回复
FILE *INFile;
char Temp[97] ;
AnsiString Temp1;
INFile = fopen("REG_N_SMOPACDL.BIN","r");

if(INFile !=NULL)
{
fseek(INFile, 0, SEEK_SET);
while(!feof(INFile))
{
fgets(Temp,98,INFile);
Temp1 = AnsiString(Temp);
memset(&aa, 0,sizeof(aa));
/*
sprintf(aa.C_ZONE,"%s",(Temp1.SubString(1,4)).c_str() );
sprintf(aa.N_SEQ,"%s",(Temp1.SubString(6,16)).c_str() );
sprintf(aa.C_ZONENO,"%s",(Temp1.SubString(23,4)).c_str() );
sprintf(aa.C_BRNO,"%s",(Temp1.SubString(29,4)).c_str() );
sprintf(aa.N_TELLER_NO,"%s",(Temp1.SubString(34,4)).c_str() );
sprintf(aa.C_ACCNO,"%s",(Temp1.SubString(38,18)).c_str() );
sprintf(aa.N_CURRTYPE,"%s",(Temp1.SubString(58,2)).c_str() );
sprintf(aa.N_OPACC_AMT,"%s",(Temp1.SubString(1,4)).c_str() );
sprintf(aa.D_WORK_DATE,"%s",(Temp1.SubString(1,4)).c_str() );
sprintf(aa.N_SCN,"%s",(Temp1.SubString(1,4)).c_str() );
sprintf(aa.D_DATA_DATE,"%s",(Temp1.SubString(1,4)).c_str() );
sprintf(aa.rev,"%s",(Temp1.SubString(1,4)).c_str() );
*///这段具体每个成员截取多少字符串,你自己确定,我没有弄,数值是乱写的。


}
}
fclose(INFile);
你这样试试,读出来数据,再处理吧,
voice1122 2010-09-02
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 zzbinfo 的回复:]
我那上面只是举例写入文件和读出文件,那个memset 是要把aa内容都置成0,你要是只要读出的操作,把前面部分去掉就可以了
[/Quote]

在我的程序中试过了,还是不行,显示s1,会把s2,S3的信息都显示出来,显示s2,会把s3的也显示出来。
有可能在生成数据文件的时候,没有考虑给每个字段值的最后加'\0'.

郁闷,不知该怎么办???
voice1122 2010-09-02
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 bigfog 的回复:]
如果没有结尾'\0',可以先复制要其他缓存中,然后添加\0,然后输出就ok了
struct tt{char s1[5];char s2[5];char s3[30];};

比如:显示s1
char ss[50];
memcpy(ss,s1,5);
ss[5]='\0';
printf(ss);
[/Quote]

这个办法我也试了,编写一个函数来取字段:
AnsiString GetFieldValue( char * src ,int len )
{
char *temp;
strncpy ( temp,src,len );
temp[len] = '\0';

return AnsiString( temp );
}
调用的时候,src就取aa.s1,。。。。
对少量的数据这个办法可以。但当数据量很大(数据文件>200M,字段很多)的时候,程序运行过程中会突然自动退出(运行界面消失,进程消失),有的时候在调试模式下能完成数据的读写。
这让我很郁闷
voice1122 2010-09-02
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 zzbinfo 的回复:]
邮件已经收到,你的数据文件有问题,根本就不是按照结构体的数据写入的,怎么能按照结构体来读取呢???这个数据文件是怎么生成的,能不能更改成结构体的数据格式,如果不能,文件的格式是不是一定的,是的话就想其他办法来读文件
[/Quote]

SAS转换成BIN文件的。估计文件格式改不了
zzbinfo 2010-09-02
  • 打赏
  • 举报
回复
把你的代码贴出来看看,是不是你在对这个结构体负值的时候有问题,这20分挣的真难呀
bigfog 2010-09-02
  • 打赏
  • 举报
回复
如果没有结尾'\0',可以先复制要其他缓存中,然后添加\0,然后输出就ok了
struct tt{char s1[5];char s2[5];char s3[30];};

比如:显示s1
char ss[50];
memcpy(ss,s1,5);
ss[5]='\0';
printf(ss);
zzbinfo 2010-09-02
  • 打赏
  • 举报
回复
邮件已经收到,你的数据文件有问题,根本就不是按照结构体的数据写入的,怎么能按照结构体来读取呢???这个数据文件是怎么生成的,能不能更改成结构体的数据格式,如果不能,文件的格式是不是一定的,是的话就想其他办法来读文件
voice1122 2010-09-02
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 zzbinfo 的回复:]
把你的代码贴出来看看,是不是你在对这个结构体负值的时候有问题,这20分挣的真难呀
[/Quote]

呵呵。抱歉
有邮箱吗,我把数据文件和数据结构发给你,帮忙看看。
谢了
voice1122 2010-09-01
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 zzbinfo 的回复:]
我是测试过的,不知道你是不是必须要用read来做这个呀。
[/Quote]

不一定用read.
我的需求是把文件中的数据读出来,写入一个数据表中。这个文件每行代表了一条记录,有N(>10000)条记录我想用一个结构来表示,方便写数据。

我的理解,你用memset预先分配内存给aa,则每次读写是否都存在分配和释放内存的过程,这样对大数据量的操作会否造成频繁的内存操作,对程序运行造成影响。

对内存操作不是很懂,特意请教。
zzbinfo 2010-09-01
  • 打赏
  • 举报
回复
我是测试过的,不知道你是不是必须要用read来做这个呀。
zzbinfo 2010-09-01
  • 打赏
  • 举报
回复
我那上面只是举例写入文件和读出文件,那个memset 是要把aa内容都置成0,你要是只要读出的操作,把前面部分去掉就可以了
CppFile 2010-09-01
  • 打赏
  • 举报
回复
你想的多了,memset的速度飞快,zzbinfo的方法很好啊,比你的方法要自然多了

[Quote=引用 6 楼 voice1122 的回复:]
引用 5 楼 zzbinfo 的回复:
我是测试过的,不知道你是不是必须要用read来做这个呀。


不一定用read.
我的需求是把文件中的数据读出来,写入一个数据表中。这个文件每行代表了一条记录,有N(>10000)条记录我想用一个结构来表示,方便写数据。

我的理解,你用memset预先分配内存给aa,则每次读写是否都存在分配和释放内存的过程,这样对大数据量的操作会否造成频繁的……
[/Quote]
voice1122 2010-08-31
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 zzbinfo 的回复:]
C/C++ code
sprintf(aa.s1,"%s","1111");
sprintf(aa.s2,"%s","2222");
sprintf(aa.s3,"%s","123123123123123123");
//ShowMessage(aa.s1);
DWORD dwBytesWritten;
HANDLE hFile = CreateFile("c:\\1.dat"……
[/Quote]

好像没有完全解决我的问题。
我现在采用了一个办法:

char temp[lenth]; //lenth是struct tt的大小;
AnsiString cs;

read( handle, &temp,lenth );
cs = temp;
然后分别用
cs.SubString(1,5);
cs.SubString(6,5);
cs.SubString(11,30);
取得tt中三个变量的值赋给相应表的字段。

但感觉有更自然的方式来操作。请教大家了
zzbinfo 2010-08-30
  • 打赏
  • 举报
回复
sprintf(aa.s1,"%s","1111");
sprintf(aa.s2,"%s","2222");
sprintf(aa.s3,"%s","123123123123123123");
//ShowMessage(aa.s1);
DWORD dwBytesWritten;
HANDLE hFile = CreateFile("c:\\1.dat",GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
if(hFile!=INVALID_HANDLE_VALUE)
{

WriteFile(hFile, &aa, sizeof(aa), &dwBytesWritten, NULL);
}
CloseHandle(hFile);
memset(&aa, 0,sizeof(aa));

hFile=CreateFile("c:\\1.dat",GENERIC_READ,NULL,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);

if(hFile!=INVALID_HANDLE_VALUE)
{
ReadFile(hFile,&aa,sizeof(aa),&dwBytesWritten, NULL);
}
CloseHandle(hFile);
ShowMessage(aa.s3);
voice1122 2010-08-30
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 cppfile 的回复:]
会把数据全部显示出来?
s1是用\0结尾的吗?

实在不行,就strncpy(tmp,tt.s1,5);
[/Quote]

不知道有没有简单的办法。
如果一个struct中的字段很多的话,用strncpy就要多写很多的代码,挺麻烦的,呵呵
CppFile 2010-08-30
  • 打赏
  • 举报
回复
会把数据全部显示出来?
s1是用\0结尾的吗?

实在不行,就strncpy(tmp,tt.s1,5);

13,825

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧