急问c++高手,怎么从一个文件里面读取network byte order的数据?

fblgzdq 2011-08-18 01:53:13
急问c++高手,怎么从一个文件里面读取network byte order的数据?

文件里面是连续的数据包, 每个包格式如下:Trade data has the following format:
Name | Offset | Num Bytes | Type |Description
Length 0 2 Integer Length of the entire package (Including this data member).
Type 2 1 Alpha "T"
Symbol 3 5 Alpha Left-justified string with spaces filling the unused bytes
Size 8 2 Integer Item size
Price 10 8 Floating Pt. Item price
Dynamic Data 18 Dynamic Alpha Reserved data; can be ignored.

就是文件里面连续的都是上面的包。

他们使用 network byte order 存储在文件里。

请问怎么样打开文件进行正确读取呢?


请问这里的network byte order 意思是binary 的存储数据地意思吗?

如何读取快呢? 如果定义一个class 表示一个包的话,由于各个包大小不一,请问包要如何定义呢?

非常感谢不吝赐教。

急!!
...全文
304 32 打赏 收藏 转发到动态 举报
写回复
用AI写文章
32 条回复
切换为时间正序
请发表友善的回复…
发表回复
一叶之舟 2011-08-19
  • 打赏
  • 举报
回复
读取出来把网络序转为主机序就可以了
赵4老师 2011-08-19
  • 打赏
  • 举报
回复
[Quote=引用 29 楼 fblgzdq 的回复:]
不知道为什么我binary 文件里面的的2byte 的整数需要倒序才对,而我的8byte 的浮点数却是不倒序才是对的?
究竟为什么呢?
[/Quote]
浮点数不倒序的话将
for (i=0;i<4;i++) SWAP(head[10+i],head[17-i]);
这句注释掉变成
//for (i=0;i<4;i++) SWAP(head[10+i],head[17-i]);
即可。
都是规定,没有为什么。'A'的ASCII码为什么是0x41?
nice_cxf 2011-08-19
  • 打赏
  • 举报
回复
float 和double 大小序是否相同这个还真是不太清楚,
http://topic.csdn.net/t/20031204/19/2528496.html 里面也是有人说需要转有人说不需要
另外大小序是跟CPU相关的,这点随便找本linux的书看下就知道了
fblgzdq 2011-08-19
  • 打赏
  • 举报
回复
不知道为什么我binary 文件里面的的2byte 的整数需要倒序才对,而我的8byte 的浮点数却是不倒序才是对的?
究竟为什么呢?
辰岡墨竹 2011-08-18
  • 打赏
  • 举报
回复
这里的head+10之后8个字节(double)或者z.x都只是用来存放字节数据,我们希望把转换后的字节直接拿来作为double或float来用。所以只能改变指针类型。不能直接(double)或(float)强制转换,那样的话C会以为把head[9]或者z.x按整数转浮点数的规则来处理,但是其实head[9]或z.x里面已经是浮点数格式了。
辰岡墨竹 2011-08-18
  • 打赏
  • 举报
回复
utohl只能处理unsigned long,它返回的值也是unsigned long,所以只用用z.x接收。
z.x = utohl(z.x); 相当于按字节顺序重新排列的z.x的四个字节。
这个时候用z.y读就是你想要的值了。
辰岡墨竹 2011-08-18
  • 打赏
  • 举报
回复
因为read时都是逐个字节的,所以文件里是什么字节顺序,就读到内存里去。但是Intel的内存变量的float字节顺序和文件里的正好相反。比如float,4个字节ABCD,读进内存去也是ABCD,可是按照Intel的内存顺序,正确的值所对应的字节是DCBA这样排的,所以它按DCBA这样顺序解释,肯定就和文件的原意不同了。
zhao4zhong1的方法我本来也想写的,但是因为有winsock里有现成的函数utohl,就直接替代了那个SWAP循环。
*((double *)(head+10))意思就是head数组的起始地址偏移10个字节,把这个地址作为double *型指针,然后按double的格式取地址里的值。
和我的float *y = (float *)(&x)意思差不多,只不过我用的x是变量,不是数组,所以它的名字不能直接当地址用,需要用&取地址。之后你要用的时候也得写*y,这个*和前面那个*((double *)(head+10))最外面的*是一个意思。
fblgzdq 2011-08-18
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 bokutake 的回复:]
嗯,刚才说的方法有些麻烦,其实用union就可以很简单处理。
struct union {
unsigned long x;
float y;
} nbof;
nbof z;
z.x = utohl(z.x);
你用z.y读数就行了。
[/Quote]

z.x = utohl(z.x);
是否应该是
z.y =utohl(z.x); ?
fblgzdq 2011-08-18
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 bokutake 的回复:]
不,浮点数一般是IEEE754格式的,比如float是32位,共4个字节,直接作为二进制的话。aaaaaaaa bbbbbbbbb ccccccccc dddddddd。大端排序就是上面那样,高位在前。而Intel的CPU处理数据的时候是小端。所以
dddddddd ccccccccc bbbbbbbbb aaaaaaaa,颠倒的是字节顺序,并不是逐个位颠倒。
你应该先避免用float来处理,……
[/Quote]

现在我是从一个binary 文件里面读数据,应该和机器cpu 无关吧。
现在文件里面有8 byte 的floating point, 下面这样做回邮问题吗?
double Price;
for (i=0;i<4;i++) SWAP(head[10+i],head[17-i]);
Price=*((double *)(head+10));

谁能解释下*((double *)(head+10));
里面的* 号和外面的 * 号 分别什么作用呢?

楼上说的:
float *y = (float *)(&x)
(&x) 这里为何要用& 呢?

谁能解释下呢?
谢谢
辰岡墨竹 2011-08-18
  • 打赏
  • 举报
回复
嗯,刚才说的方法有些麻烦,其实用union就可以很简单处理。
struct union {
unsigned long x;
float y;
} nbof;
nbof z;
z.x = utohl(z.x);
你用z.y读数就行了。


辰岡墨竹 2011-08-18
  • 打赏
  • 举报
回复
不,浮点数一般是IEEE754格式的,比如float是32位,共4个字节,直接作为二进制的话。aaaaaaaa bbbbbbbbb ccccccccc dddddddd。大端排序就是上面那样,高位在前。而Intel的CPU处理数据的时候是小端。所以
dddddddd ccccccccc bbbbbbbbb aaaaaaaa,颠倒的是字节顺序,并不是逐个位颠倒。
你应该先避免用float来处理,因为unsigned long和float是一样长的,所以你可以先用一个unsigned long存储数据,然后用utohl函数把它转换为本地字节序。取返回值的地址,并强制转换为一个float指针来用。
比如utohl返回值存放在unsigned long x里,用float *y = (float *)(&x);。这样*y就可以当作float来用了。
注意不能直接把x用(float)转换为y,那样的话x的内容会被按照整数(其实是IEE754)来解释。
fblgzdq 2011-08-18
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 nice_cxf 的回复:]
需不需要是要看你机器CPU,如果是X86的CPU就需要转,其他的要看具体什么型号,如果你觉得转数据不对的话,你可以去掉转换看看数据是否正确
[/Quote]

应该和机器无关吧
fblgzdq 2011-08-18
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 nice_cxf 的回复:]
需不需要是要看你机器CPU,如果是X86的CPU就需要转,其他的要看具体什么型号,如果你觉得转数据不对的话,你可以去掉转换看看数据是否正确
[/Quote]

应该和byte 无关吧。
fblgzdq 2011-08-18
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 babilife 的回复:]
引用 3 楼 thefirstz 的回复:
network byte order是网络字节顺序,按大端进行数据传送
楼主可以先读出来,然后调用一些函数如ntohl之类的转为本地的数据存储格式

++
需要做相关的字节顺转换
[/Quote]

请问8bytes 的floating point 浮点数是否也要 12345678变成87654321 byte 顺序。 每个byte 是否还要转呢?
非常感谢
至善者善之敌 2011-08-18
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 thefirstz 的回复:]
network byte order是网络字节顺序,按大端进行数据传送
楼主可以先读出来,然后调用一些函数如ntohl之类的转为本地的数据存储格式
[/Quote]
++
需要做相关的字节顺转换
nice_cxf 2011-08-18
  • 打赏
  • 举报
回复
需不需要是要看你机器CPU,如果是X86的CPU就需要转,其他的要看具体什么型号,如果你觉得转数据不对的话,你可以去掉转换看看数据是否正确
fblgzdq 2011-08-18
  • 打赏
  • 举报
回复
浮点数是否应该原来的12345678位要倒换顺序变成87654321呢?
就像上面的code 做的这样呢?

有人能解答下吗?
非常感谢
fblgzdq 2011-08-18
  • 打赏
  • 举报
回复
是不是2位的integer 4位的integer 8位的double 浮点数,都是原来的12345678位要倒换顺序变成87654321呢?
就像上面的code 一样。
但是结果好像不太对。
特别是浮点数非常长, 有的整数又好像少了2个零

非常感谢。


fblgzdq 2011-08-18
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 zhao4zhong1 的回复:]
C/C++ code
// Trade data has the following format:
// Name | Offset | Num Bytes | Type | Description
// -------------+--------+-----------+---------------+-------------------------……
[/Quote]

请问一下如果要把结果直接打印到另一个文件里面去要如何写呢?
如果要同时打印到文件和显示到屏幕要如何做呢?

不知道这个integer 转换的原理如何?
有些结果似乎不太对。
非常感谢。
赵4老师 2011-08-18
  • 打赏
  • 举报
回复
// Trade data has the following format:
// Name | Offset | Num Bytes | Type | Description
// -------------+--------+-----------+---------------+-----------------------------------------------------------
// Length | 0 | 2 | Integer | Length of the entire package (Including this data member).
// Type | 2 | 1 | Alpha | "T"
// Symbol | 3 | 5 | Alpha | Left-justified string with spaces filling the unused bytes
// Size | 8 | 2 | Integer | Item size
// Price | 10 | 8 | Floating Pt. | Item price
// Dynamic Data | 18 | | Dynamic Alpha | Reserved data; can be ignored.
#include <stdio.h>
#include <string.h>
#define SWAP(a,b) (a)^=(b)^=(a)^=(b)
FILE *f;
int i,n,r,DL;
char head[18];

unsigned short Length;
char Type;
char Symbol[6];
unsigned short Size;
double Price;
char Dynamic_Data[65518];

void main() {
f=fopen("data.bin","rb");
if (NULL==f) {
printf("Can not open file data.bin!\n");
return;
}
n=0;
while (1) {
r=fread(head,1,18,f);
if (r<18) break;
SWAP(head[0],head[1]);
Length=*((unsigned short *)head);
Type=head[2];
if ('T'!=Type) break;
strncpy(Symbol,head+3,5);Symbol[5]=0;
SWAP(head[8],head[9]);
Size=*((unsigned short *)(head+8));
for (i=0;i<4;i++) SWAP(head[10+i],head[17-i]);
Price=*((double *)(head+10));
DL=Length-18;
if (DL>0) {
r=fread(Dynamic_Data,1,DL,f);
if (r<DL) break;
}
n++;
printf("Pack %06d: Length=%hd,Type=%c,Symbol=%s,Size=%hd,Price=%lg,Dynamic Data Length=%d\n",n,Length,Type,Symbol,Size,Price,DL);
}
fclose(f);
}
加载更多回复(12)

64,682

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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