[英]Bit Manipulation on char array in c
If I am given a char array of size 8, where I know the the first 3 bytes are the id, the next byte is the message, and the last 3 bytes are the values.如果给我一个大小为 8 的字符数组,我知道前 3 个字节是 id,下一个字节是消息,最后 3 个字节是值。 How could I use bit manipulation in order to extract the message.
我如何使用位操作来提取消息。
Example: a char array contains 9990111 (one integer per position), where 999 is the id, 0 is the message, and 111 is the value.示例:char 数组包含 9990111(每个位置一个整数),其中 999 是 id,0 是消息,111 是值。
Any tips?有小费吗? Thanks!
谢谢!
Given:鉴于:
the array contains {'9','9','9','0','1','1','1'}
数组包含 {'9','9','9','0','1','1','1'}
Then you can convert with sscanf()
:然后您可以使用
sscanf()
进行转换:
char buffer[8] = { '9', '9', '9', '0', '1', '1', '1', '\0' };
//char buffer[] = "9990111"; // More conventional but equivalent notation
int id;
int message;
int value;
if (sscanf(buffer, "%3d%1d%3d", &id, &message, &value) != 3)
…conversion failed…inexplicably in this context…
assert(id == 999);
assert(message == 0);
assert(value == 111);
But there's no bit manipulation needed there.但是那里不需要任何操作。
The usual way would be to define a structure with members which are bit fields and correspond to the segmented information in your array.通常的方法是定义一个结构,其成员是位字段并对应于数组中的分段信息。 (oh, re-reading your question: is the array filled with
{ '9', '9',...}
?? Then you'd just sscanf the values with the proper offset into the array. (哦,重新阅读您的问题:数组是否填充了
{ '9', '9',...}
?? 然后您只需将具有适当偏移量的值扫描到数组中。
Well, if you want bit manipulation, no matter what, here it goes:好吧,如果你想要位操作,无论如何,这里是:
#include <stdio.h>
#include <arpa/inet.h>
int main(void) {
char arr[8] = "9997111";
int msg = 0;
msg = ((ntohl(*(uint32_t *) arr)) & 0xff) - 48;
printf("%d\n", msg);
return 0;
}
Output:输出:
7
Just remember one thing... this does not comply with strict aliasing rules.请记住一件事......这不符合严格的别名规则。 But you can use some memcpy() stuff to solve it.
但是你可以使用一些 memcpy() 的东西来解决它。
Edit #1 (parsing it all, granting compliance with strict aliasing rules, and making you see that this does not make any sense):编辑 #1(解析所有内容,遵守严格的别名规则,并让您看到这没有任何意义):
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <arpa/inet.h>
int main(void) {
char arr[8] = "9997111";
uint32_t a[2];
unsigned int id = 0, msg = 0, val = 0;
memcpy(a, arr, 4);
memcpy(&a[1], arr + 4, 4);
a[0] = ntohl(a[0]);
a[1] = ntohl(a[1]);
id = ((((a[0] & 0xff000000) >> 24) - 48) * 100) + ((((a[0] & 0xff0000) >> 16)- 48) * 10) + (((a[0] & 0xff00) >> 8)- 48);
msg = (a[0] & 0xff) - 48;
val = ((((a[1] & 0xff000000) >> 24) - 48) * 100) + ((((a[1] & 0xff0000) >> 16)- 48) * 10) + (((a[1] & 0xff00) >> 8)- 48);
printf("%d\n", id);
printf("%d\n", msg);
printf("%d\n", val);
return 0;
}
Output:输出:
999
7
111
You can use Memory Copy to extract the values.您可以使用内存复制来提取值。 Here is an example
这是一个例子
char *info = malloc(sizeof(int)*3);
char *info2 = malloc(sizeof(int)*1);
char *info3 = malloc(sizeof(int)*3);
memcpy(info,msgTest, 3);
memcpy(info2,msgTest+3, 1);
memcpy(info3,msgTest+4, 3);
printf("%s\n", msgTest);
printf("ID is %s\n", info);
printf("Code is %s\n", info2);
printf("Val is %s\n", info3);
Lets say string msgTest = "0098457让我们说字符串 msgTest = "0098457
The print statement willl goes as follows..打印语句如下..
ID is 009 Code is 8 Val is 457 ID 是 009 代码是 8 Val 是 457
Hope this helps, Good luck!希望这有帮助,祝你好运!
here is an example in which i don't use malloc or memory copy for a good implementation on embedded devices, where the stack is limited.这是一个示例,其中我不使用 malloc 或内存副本来在堆栈有限的嵌入式设备上实现良好的实现。 Note there is no need to use compact because it is only 1 byte.
注意没有必要使用compact,因为它只有1 个字节。 This is C11 implementation.
这是 C11 实现。 If you have 4 Bytes for example to be analyzed, create another struct with 4 charbits, and copy the address to the new struct instead.
例如,如果要分析 4 个字节,请创建另一个具有 4 个字符位的结构,并将地址复制到新结构中。 This is coinstance with design patterns concept for embedded.
这与嵌入式设计模式的概念是一致的。
#include <stdio.h>
// start by creating a struct for the bits
typedef struct {
unsigned int bit0:1; //this is LSB
unsigned int bit1:1; //bit 1
unsigned int bit2:1;
unsigned int bit3:1;
unsigned int bit4:1;
unsigned int bit5:1;
unsigned int bit6:1;
unsigned int bit7:1;
unsigned int bit8:1;
}charbits;
int main()
{
// now assume we have a char to be converted into its bits
char a = 'a'; //asci of a is 97
charbits *x; //this is the character bits to be converted to
// first convert the char a to void pointer
void* p; //this is a void pointer
p=&a; // put the address of a into p
//now convert the void pointer to the struct pointer
x=(charbits *) p;
// now print the contents of the struct
printf("b0 %d b1 %d b2 %d b3 %d b4 %d b5 %d b6 %d b7 %d", x->bit0,x->bit1, x->bit2,x->bit3, x->bit4, x->bit5, x->bit6, x->bit7, x->bit8);
// 97 has bits like this 01100001
//b0 1 b1 0 b2 0 b3 0 b4 0 b5 1 b6 1 b7 0
// now we see that bit 0 is the LSB which is the first one in the struct
return 0;
}
// thank you and i hope this helps
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.