C将char复制到struct

时间:2011-11-21 14:46:41

标签: c

我读了一堆输入(传感器),我得到每个传感器的0(关闭)或1(开启)。我在char *中获得这些值,其中我得到了所有传感器的结果。每个传感器都有1位。

当我想在我的代码中使用这些值时,我觉得将这个结果与另一个带有我感兴趣的一位字符的char结果并不是一个好主意,因为代码变得非常臃肿。

相反,我想要制作一个像这样的结构:

struct sensors {
    unsigned int Sensor0:1;
    unsigned int Sensor1:1;
    unsigned int Sensor2:1;
    unsigned int Sensor3:1;
    unsigned int Sensor4:1;
    unsigned int Sensor5:1;
    unsigned int Sensor6:1;
    unsigned int Sensor7:1;
}  

struct sensors s1;
memcpy(buf, (char*)&sensors, 1);

但是从我读过的内容中,结构可能不会在内存中相互保存每个组件,并且可能会在其间插入填充和其他内容,这使得它不再适用。

我错了吗?有没有更好的方法来做到这一点?

4 个答案:

答案 0 :(得分:4)

根据您当前的struct sensors定义,编译器将插入额外的填充,因为int具有对齐要求,通常在sizeof(int)边界上。此外,int必须宽于char,因此它可以容纳超过8个标志,这是您不需要的。

如果你这样声明(改为使用unsigned char),则应该没有填充,因为char具有最不严格的对齐要求:

struct sensors {
    unsigned char Sensor0:1;
    unsigned char Sensor1:1;
    unsigned char Sensor2:1;
    unsigned char Sensor3:1;
    unsigned char Sensor4:1;
    unsigned char Sensor5:1;
    unsigned char Sensor6:1;
    unsigned char Sensor7:1;
}

这可能不仅适用于CHAR_BIT != 8的非常奇怪的平台。

答案 1 :(得分:2)

添加到Blagovest的答案:

比特场方法看似合理。但是,您必须指示编译器不在字段之间引入填充。对于GCC,这是通过在结构定义之后放置__attribute__ ((packed))来完成的,如下所示:

struct sensors {
    unsigned char Sensor0:1;
    unsigned char Sensor1:1;
    unsigned char Sensor2:1;
    unsigned char Sensor3:1;
    unsigned char Sensor4:1;
    unsigned char Sensor5:1;
    unsigned char Sensor6:1;
    unsigned char Sensor7:1;
} __attribute__ ((packed)); 

请注意,4.4之前的GCC用于为char字段引入填充,而不管此指令;有关详细信息,请参阅the documentation on warning option -Wpacked-bitfield-compat

答案 2 :(得分:0)

如果您想要超级安全,可以使用具有一位设置的字符进行AND。您可能希望使用数组而不是结构来执行此操作。你可以将它包装成一个漂亮的循环,它根本没用多少。

但是,任何理智的C编译器都会将无符号整数放在连续的内存中,所以做某种类似的复制应该是安全的。当存在不同大小的类型时,编译器通常只会添加额外的填充。不幸的是我不知道这是否适合您,因为你有命令memcpy(buf,(char *)& sensors,1)会将你的传感器数据字节复制到第一个整数 - 这不是你想要的。

答案 3 :(得分:0)

我会使用memcpy()来访问Blagovest Buyukliev answer中定义的数据,而不是union

union combSensors {
    unsigned char all_fields;
    struct sensors field_by_field;
}