我有一个unsigned char数组,其中包含如下所示的十六进制字节:
unsigned char array[255];
array[0] = 'F';
array[1] = 'F';
array[2] = 'E';
array[3] = '2';
array[4] = 'A';
array[5] = 'A';
array[6] = 'C';
array[7] = 'C';
我想合并它们以便它变成:
array[0] = "FF"
array[1] = "E2"
array[2] = "AA"
array[3] = "CC"
array[0] = '\xFF';
array[1] = '\xE2';
array[2] = '\xAA';
array[3] = '\xCC';
我尝试过使用sprintf
,但后来我不知道如何在其中指定索引号。任何帮助。?
答案 0 :(得分:2)
因此,您希望将由十六进制字符组成的字符串转换为字节数组,对吗?了解您的数据。
int char2hexa(unsigned char c)
{
if(c >= '0' && c <= '9') {
return (c - '0'); /* will return 0-9 */
} else if(c >= 'A' && c <= 'F') {
return (c - 'A') + 10; /* will return 10-15 */
} else if(c >= 'a' && c <= 'f') {
return (c - 'a') + 10; /* will return 10-15 */
} else {
return -1;
}
}
无法帮助您,因为它会生成字符串。相反,您需要提取每个hexa字符的“值”,并使用它来计算字节值。
因此,让我们创建一个辅助函数将十六进制字符转换为整数值(如果无效则为-1)。我们将使用字符的ASCII值以及字符范围在ASCII表中连续的事实
unsigned char hexvals2byte(int upper, int lower)
{
return (upper * 16 + lower);
}
现在一个字节将由两个hexa值构成,使用一个作为高半字节(乘以16或向左移动4),另一个作为低半字节,所以让我们有一个函数:
#include <stdio.h>
#include <stdlib.h>
unsigned char array[255];
array[0] = 'F';
array[1] = 'F';
array[2] = 'E';
array[3] = '2';
array[4] = 'A';
array[5] = 'A';
array[6] = 'C';
array[7] = 'C';
unsigned length = 8;
int upper, lower;
for(int i = 0; i < length; i+=2) {
upper = char2hexa(array[i]);
lower = char2hexa(array[i+1]);
if(upper < 0 || lower < 0) {
/* handle input data format error */
fprintf(stderr, "ERROR: Cannot decode hexa values '%c%c'\n", array[i], array[i+1]);
exit(EXIT_FAILURE);
}
array[i/2] = hexvals2byte(upper, lower);
}
将各个部分放在一起。我会假设:
来了。
{{1}}
答案 1 :(得分:1)
所以你需要一个unsigned char result[128][3]
的结果数组,然后分配部分结果,将2个源元素分组到一个结果子元素中:
unsigned char result[128][3] = { 0 };
int i;
for (i = 0; i < 255; ++i)
{
result[i/2][i%2] = array[i];
}
大小3的原因是,你需要2个字符和一个零分隔符来形成一个字符串。
答案 2 :(得分:1)
将数字转换为数字的简便方法是从中减去'0'
:
char digit = '3';
int number = digit - '0'; /* number = 3 */
这仅适用于数字(digit >= '0' && digit <= '9'
),十六进制数字('A'
,'B'
等),您必须做更多工作:
unsigned char result[127];
int i;
unsigned char current;
unsigned char calc_diff(unsigned char digit) {
if(digit >= '0' && digit <= '9')
return '0';
else if(digit >= 'A' && digit <= 'F')
return 'A' - 10;
else if(digit >= 'a' && digit <= 'f')
return 'a' - 10;
else
return 0; // handle invalid digit
}
for(i = 0; i < 128; ++i) {
current = array[2 * i];
result[i] = (current - calc_diff(current)) << 4;
current = array[(2 * i) + 1];
result[i] |= current - calc_diff(current);
}
答案 3 :(得分:1)
您希望将字符转换为十六进制值并将它们成对组合。
这是一个简单的程序,用于说明如何执行此操作:
#include <stdio.h>
#include <string.h>
static int xdigit(unsigned char c) {
/* this method is inefficient but works for all encodings */
static const char xdigits[] = "abcdef0123456789ABCDEF";
const char *p = memchr(xdigits, c, 22);
return p ? (p - xdigits + 10) & 15 : -1;
}
int main(void) {
unsigned char array[255];
while (scanf("%254s", array) == 1) {
int i, j, d, d2 = 0;
for (i = j = 0; array[i] != '\0'; i++) {
d = xdigit(array[i]);
if (d < 0) {
printf("invalid hexadecimal digit: %c\n", array[i]);
break;
}
d2 = (d2 << 4) | d;
if (i & 1) {
array[j++] = (unsigned char)d2;
d2 = 0;
}
}
array[j] = '\0';
printf("converted array: %s\n", array);
}
return 0;
}
这是一个更复杂的版本,具有单独的转换功能和更明确的输出:
#include <ctype.h>
#include <stdio.h>
#include <string.h>
static int xdigit(unsigned char c) {
switch (c) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
return c - '0';
case 'A': case 'a':
return 10;
case 'B': case 'b':
return 11;
case 'C': case 'c':
return 12;
case 'D': case 'd':
return 13;
case 'E': case 'e':
return 14;
case 'F': case 'f':
return 15;
default:
return -1;
}
}
int xconvert(unsigned char *dest, const unsigned char *src, int len) {
int i, j, d, d2 = 0;
for (i = j = 0; i < len; i++) {
d = xdigit(src[i]);
if (d < 0) {
printf("invalid hexadecimal digit: %c\n", src[i]);
return -1;
}
d2 = (d2 << 4) | d;
if (i & 1) {
dest[j++] = (unsigned char)d2;
d2 = 0;
}
}
if (i & 1) {
printf("missing trailing digit\n");
return -1;
}
return j;
}
int main(void) {
unsigned char array[255];
int i, len, c;
while (scanf("%254s", array) == 1) {
len = xconvert(array, array, strlen((char *)array));
if (len >= 0) {
printf("converted array: \"");
for (i = 0; i < len; i++) {
c = array[i];
if (isprint(c)) {
putchar(c);
} else {
printf("\\x%02X", c);
}
}
printf("\"\n");
}
}
return 0;
}
答案 4 :(得分:0)
我想你混淆了一个8位值(例如0x0F
,十进制为15),字符值如'F'
(对应于ASCII格式的70
)字符串文字"FF"
(对应于指向三个字符值{'F','F','\0'}
的序列的指针。
从您提供的上下文中,您似乎意味着8位值,它们由数据类型unsigned char
表示。
鉴于此,代码可能如下所示:
unsigned char array[255] = { 0xF,0xE,0x2,0xA,0xA,0xC,0xC };
int target=0;
for (int i=0; i<254; i+=2) {
array[target] = (array[i] << 4) + array[i+1];
target++;
}
答案 5 :(得分:0)
我刺伤了它。在这里你必须知道数组的大小。在你的情况下255
//counters and array's
int first = 0;
int second = 0;
int count = 0;
char foo[8] = {'F', 'F', 'E', '2', 'A', 'A', 'C', 'C'};
//array half the size of the first one.
char *done[4];
//loop through first array
while (first <= 7)
{
//if its the first letter
if (second == 0)
{
//allocate enough mem to second arr
done[count] = (char *)malloc(sizeof(char *) * 3);
//assaign the first letter
done[count][0] = foo[first];
//indicate the next step for the second letter
second = 1;
}
//if its the second letter
else if (second == 1)
{
//assign second letter
done[count][1] = foo[first];
//null the string
done[count][2] = '\0';
//increase posistion index for the second arr
count++;
//indicate nexxt step is a the first letter of the next step
second = 0;
}
//increment the index for the first arr
first++;
}
答案 6 :(得分:0)
鉴于数据是ASCII格式,并且您想将其合并为原始二进制格式,那么:
for(size_t i=0; i<n; i++)
{
array[i] = to_int(array[i]);
}
其中to_int()
是从十六进制ASCII转换为整数的自定义例程。也就是说,如果数字用'0'
减去,否则如果用大写字母减去'A'
并添加0xA。
然后,合并项目:
for(size_t i=0; i<n; i+=2)
{
array[i] = (unsigned int)array[i]<<4 | array[i+1];
}
答案 7 :(得分:-1)
也许有不确定的事情,但也许你想这样做。
#include <stdio.h>
int main(void){
unsigned char array[255] = {//or char -> hex byte
'\xF', '\xF', '\xE', '\x2',
'\xA', '\xA', '\xC', '\xC',
};
int len = 8;
for(int i = 0, j = 0; i < len; i += 2){
array[j++] = (array[i] << 4) | array[i+1];
}
len = len / 2;
for(int i = 0; i < len; i++){
printf("%02hhX", array[i]);//FFE2AACC
}
printf("\n");
}
首先保存的数据是十六进制字符
#include <stdio.h>
#include <ctype.h>
int main(void){
unsigned char array[255] = {
'F', 'F', 'E', '2',
'A', 'A', 'C', 'C',
};
int len = 8;
for(int i = 0, j = 0; i < len; i++){
if(isxdigit(array[i])){//maybe redundant
if(isdigit(array[i])){
array[i] -= '0';
} else {
array[i] -= isupper(array[i]) ? 'A' : 'a';
array[i] += 10;
}
} else {
fprintf(stderr, "invalid data %c\n", array[i]);
return -1;
}
}
for(int i = 0, j = 0; i < len; i += 2){
array[j++] = (array[i] << 4) | array[i+1];
}
len = len / 2;
for(int i = 0; i < len; i++){
printf("%02hhX", array[i]);
}
printf("\n");
}