r*****8 发帖数: 2560 | 1 C语言,结构体转字符串。简单的难题
结构体转字符串怎么做?我有一个野外站点,通过铱星发回来数据,10个字符1分
钱。为了降低费用,要压缩字符数量。结构体的位域(bit fields)很理想,以下例子
3个数据只要2个字符就够了。
结构体做好以后,要用字符传送(short burst message),怎么把结构体变成字
符串?我用的是个笨办法,把结构体写入一个文件。然后把文件的字符串读出来。
各位大侠有更好的方法吗?
如果有时间细看以下是程序。
// #############################################
#include // Standard input output.
#include // Standard library.
#include // String handling
#include /* POSIX terminal control definitions */
#include /* UNIX standard function definitions */
#include /* File control definitions */
#define _GNU_SOURCE
// 定义结构体
struct packed_struct {
unsigned int f1:8;
unsigned int f2:5;
unsigned int f3:3;
} pack;
int main() {
struct packed_struct packed_data = {0};
// 给结构体赋值
packed_data.f1 = 45;
packed_data.f2 = 14;
packed_data.f3 = 0;
// 写入文件
FILE * output;
output = fopen("Data.dat", "wb");
fwrite(&packed_data, sizeof(packed_data), 1, output);
fclose(output);
// 从文件读出
int fd = open ("Data.dat", O_RDWR);
char recovered_data[100];
memset(recovered_data, 0, 100);
int n= read (fd, recovered_data, sizeof(recovered_data));
recovered_data[n] = '\0';
// put '\0' to terminate the string.
close(fd);
// 检查一切正确
int i=0;
for(i=0; i<32; i++){
printf("%i, %i\n", i, recovered_data[i]);
} |
d****i 发帖数: 4809 | 2 Using a file to convert back and forth is a waste. You can simply use a
pointer to your struct data to do the transfer. But bear in mind that the
way you wrote may cause issue mainly due to two reasons:
1. Compiler can do some padding to struct
2. Endianess issue (big/little endian)
So in order to make it correct during network transmission, you first want
to make sure that compiler padding is removed, so you can use #pramga
directive:
#pragma pack(1)
struct packed_struct {
unsigned int f1:8;
unsigned int f2:5;
unsigned int f3:3;
} pack;
Fortunately, your bit fields do not break in between one byte alignment. So
using the above technique, your bytes won't be garbled. And you can make
sure that sizeof(pack)=2.
Then in order to make it work for all CPU architectures (big/little endian),
you need to use htons() and ntohs() functions. You can refer to the
following manpage:
http://pubs.opengroup.org/stage7tc1/functions/htonl.html
Then finally you want to put all your struct into a char[2] array and then
fire it and let it go!
【在 r*****8 的大作中提到】 : C语言,结构体转字符串。简单的难题 : 结构体转字符串怎么做?我有一个野外站点,通过铱星发回来数据,10个字符1分 : 钱。为了降低费用,要压缩字符数量。结构体的位域(bit fields)很理想,以下例子 : 3个数据只要2个字符就够了。 : 结构体做好以后,要用字符传送(short burst message),怎么把结构体变成字 : 符串?我用的是个笨办法,把结构体写入一个文件。然后把文件的字符串读出来。 : 各位大侠有更好的方法吗? : 如果有时间细看以下是程序。 : // ############################################# : #include // Standard input output.
|
r*****8 发帖数: 2560 | 3 ADBC,非常感谢指点。
实际数据中有很多跨字节、破字节的数值,字节序(endianess)的问题我已
经遇到了。还好我们的数据不是向公众传递,自己内部几台机器做相应的调整就好了。
“You can simply use a pointer to your struct data to do the transfer.”
我总觉得存盘的步骤可以省略。可是我试了几次都不行,劳驾您再说清楚一些。我
试了这个,编译通不过:
char * char_pointer;
char_pointer = &packed_data;
指针怎么用,我不太懂。
即使忽略警告,我怎么读指针的每一位的内容?
char_pointer+1
char_pointer+2
里面的内容怎么读出来?
【在 d****i 的大作中提到】 : Using a file to convert back and forth is a waste. You can simply use a : pointer to your struct data to do the transfer. But bear in mind that the : way you wrote may cause issue mainly due to two reasons: : 1. Compiler can do some padding to struct : 2. Endianess issue (big/little endian) : So in order to make it correct during network transmission, you first want : to make sure that compiler padding is removed, so you can use #pramga : directive: : #pragma pack(1) : struct packed_struct {
|
d****i 发帖数: 4809 | 4 You need to create a unsigned char[2] array, and then copy the data from
struct to char array, and then invokw the system call send() to send bytes.
See:
http://pubs.opengroup.org/onlinepubs/7908799/xns/send.html
I think actually you don't need to use htons since there are no fields
larger than 1 byte in your struct.
【在 r*****8 的大作中提到】 : ADBC,非常感谢指点。 : 实际数据中有很多跨字节、破字节的数值,字节序(endianess)的问题我已 : 经遇到了。还好我们的数据不是向公众传递,自己内部几台机器做相应的调整就好了。 : “You can simply use a pointer to your struct data to do the transfer.” : 我总觉得存盘的步骤可以省略。可是我试了几次都不行,劳驾您再说清楚一些。我 : 试了这个,编译通不过: : char * char_pointer; : char_pointer = &packed_data; : 指针怎么用,我不太懂。 :
|
r*****8 发帖数: 2560 | 5 “You need to create a unsigned char[2] array, and then copy the data from
struct to char array,”
这两句编译通不过:
unsigned char char_array[2];
strcpy(char_array, packed_data);
还有,不能strcpy,因为真实数据中间可能有0x0字符,strcpy 到了0x0字符就
不往下走了。
要读出每一个位置来,如果是指针,这也是不好办的。
发送我有经验,不是问题。
.
【在 d****i 的大作中提到】 : You need to create a unsigned char[2] array, and then copy the data from : struct to char array, and then invokw the system call send() to send bytes. : See: : http://pubs.opengroup.org/onlinepubs/7908799/xns/send.html : I think actually you don't need to use htons since there are no fields : larger than 1 byte in your struct.
|
k******t 发帖数: 1498 | 6 你这个有没有可能上功能强点的处理器,比如cortex-M3之类的?直接压缩,这种数据,
压缩比很容易到5甚至更高。
【在 r*****8 的大作中提到】 : C语言,结构体转字符串。简单的难题 : 结构体转字符串怎么做?我有一个野外站点,通过铱星发回来数据,10个字符1分 : 钱。为了降低费用,要压缩字符数量。结构体的位域(bit fields)很理想,以下例子 : 3个数据只要2个字符就够了。 : 结构体做好以后,要用字符传送(short burst message),怎么把结构体变成字 : 符串?我用的是个笨办法,把结构体写入一个文件。然后把文件的字符串读出来。 : 各位大侠有更好的方法吗? : 如果有时间细看以下是程序。 : // ############################################# : #include // Standard input output.
|
r*****8 发帖数: 2560 | 7 每次送的数据量很少,只有10-20个数据,每个数据的大小只有几百以内的整数。
几乎没法压缩。
据,
【在 k******t 的大作中提到】 : 你这个有没有可能上功能强点的处理器,比如cortex-M3之类的?直接压缩,这种数据, : 压缩比很容易到5甚至更高。
|
k******t 发帖数: 1498 | 8 你对实时性的要求高么?如果不高的话可以把把几个数据包拼起来之后再压缩。我以前
做传感器网络,用手机网络上传数据,一个数据包9个字节,凑够100个数据包之后可以
压缩到不到100byte.
【在 r*****8 的大作中提到】 : 每次送的数据量很少,只有10-20个数据,每个数据的大小只有几百以内的整数。 : 几乎没法压缩。 : : 据,
|
r*****8 发帖数: 2560 | 9 你提供的信息很重要,值得考虑。
不过目前还是要先做一个每次观测都传回来的,下一步再考虑合并几次观测。
【在 k******t 的大作中提到】 : 你对实时性的要求高么?如果不高的话可以把把几个数据包拼起来之后再压缩。我以前 : 做传感器网络,用手机网络上传数据,一个数据包9个字节,凑够100个数据包之后可以 : 压缩到不到100byte.
|
k******t 发帖数: 1498 | 10 数据的产生传输和使用完全是你们自己,可以相当灵活。还可以考虑建立字典。
【在 r*****8 的大作中提到】 : 你提供的信息很重要,值得考虑。 : 不过目前还是要先做一个每次观测都传回来的,下一步再考虑合并几次观测。
|
|
|
d****i 发帖数: 4809 | 11 Don't use strcpy, it is used to copy string only. Use memcpy, or use direct
assign:
char_array[0] = packed_data.f1;
char_array[1] = packed_data.f2 << 3 + packed_data.f3;
【在 r*****8 的大作中提到】 : “You need to create a unsigned char[2] array, and then copy the data from : struct to char array,” : 这两句编译通不过: : unsigned char char_array[2]; : strcpy(char_array, packed_data); : 还有,不能strcpy,因为真实数据中间可能有0x0字符,strcpy 到了0x0字符就 : 不往下走了。 : 要读出每一个位置来,如果是指针,这也是不好办的。 : 发送我有经验,不是问题。 :
|
f****4 发帖数: 1359 | 12 struct packed_struct packed_data = {0};
packed_data.f1 = 45;
packed_data.f2 = 14;
packed_data.f3 = 0;
char buffer[2];
memcpy( buffer, &packed_data, sizeof(packed_struct));
struct packed_struct *ptr = (struct packed_struct *) buffer;
cout<< sizeof(packed_struct) <
cout<< sizeof(buffer) <
cout<f1<
cout<f2<
cout<f3< |
r*****8 发帖数: 2560 | 13 谢谢回复。
有你们的指点,目前为止,进展顺利。
我慢慢消化一下,再来跟你们报告结果。 |
S*A 发帖数: 7142 | 14 你根本就不需要copy 的。
直接指针转换就可以了。
unsigned char *data = (unsigned char *) &packet_struct;
int datasize = len(sizeof packet_struct);
然后直接使用 data 指针就可以了, size 就是 datasize。 |
r*****8 发帖数: 2560 | 15 谢谢各位高人的指点!回来向各位高人汇报一下。
程序完成,连续运行了半个月左右了,功能正常。我的结论:如果要节约字节(如
卫星传输),把数据转成二进制位元(bit)最省字节。结构体(structure, bit
field)比较简单,但是,要多用大约40%的字节。
压缩数据没有试,不好想象,每个位元都用上了,猜想压缩空间不大。 |