如果给出一个大小为8的char数组,我知道前3个字节是id,下一个字节是消息,最后3个字节是值。我怎么能使用位操作来提取消息。
示例:char数组包含9990111(每个位置一个整数),其中999是id,0是消息,111是值。
任何提示?谢谢!
答案 0 :(得分:4)
假设:
数组包含{'9','9','9','0','1','1','1'}
然后您可以使用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);
但那里不需要任何操作。
答案 1 :(得分:0)
通常的方法是定义一个结构,其成员是位字段,对应于数组中的分段信息。 (哦,重新阅读你的问题:数组是否填充了{ '9', '9',...}
??然后你只需要在数组中使用适当的偏移量来扫描这些值。
答案 2 :(得分:0)
好吧,如果你想要位操作,无论如何,这里都是:
#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;
}
输出:
7
记住一件事......这不符合严格的别名规则。但你可以用一些memcpy()来解决它。
编辑#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;
}
输出:
999
7
111
答案 3 :(得分:0)
您可以使用“内存复制”来提取值。这是一个例子
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);
让我们说字符串msgTest =&#34; 0098457
print语句将如下所示..
ID为009 代码是8 Val是457
希望这有帮助,祝你好运!
答案 4 :(得分:0)
这是一个示例,其中我不使用 malloc 或内存复制来在堆栈有限的嵌入式设备上实现良好的实现。注意没有必要使用 compact 因为它只有 1 个字节。这是 C11 实现。例如,如果要分析 4 个字节,请创建另一个具有 4 个字符位的结构,并将地址复制到新结构中。这与嵌入式设计模式的概念是一致的。
#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