C:使用正则表达式将十六进制字符串分隔为字符

C:使用正则表达式将十六进制字符串分隔为字符,c,arrays,regex,string,hex,C,Arrays,Regex,String,Hex,我想转换十六进制字符串,如: FE2A8D0000CA372D4F461B1D9A1883A32F018823FF60D300004844200000D0A0F2703000000000B0040307000356A3 转换为以下格式: const char msg[] = {0xFE, 0x2A, 0x8D, 0x00, 0x00, 0xCA, 0x37, 0x2D, 0x4F, 0x46, 0x1B, 0x1D, 0x9A, 0x18, 0x83, 0xA3, 0x2F, 0x01, 0x8

我想转换十六进制字符串,如:

FE2A8D0000CA372D4F461B1D9A1883A32F018823FF60D300004844200000D0A0F2703000000000B0040307000356A3

转换为以下格式:

const char msg[] = {0xFE, 0x2A, 0x8D, 0x00, 0x00, 0xCA, 0x37, 0x2D, 0x4F,
0x46, 0x1B, 0x1D, 0x9A, 0x18, 0x83, 0xA3, 0x2F, 0x01, 0x88, 0x23, 0xFF,
0xFF, 0x60, 0xD3, 0x00, 0x00, 0x48, 0x42, 0x00, 0x00, 0x0D, 0x0A, 0x0F,
0x27, 0x03, 0x00, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00, 0xB0, 0x04, 0x03,
0x07, 0x00, 0x03, 0x56, 0xA3};
目前,我在记事本++中使用正则表达式,效果很好。 这是正则表达式:

find: ([a-z0-9]{2})
replace with: \, 0x\1
(then I remove the first ',')
我用C语言编写代码,我尝试过使用正则表达式,但我无法让它工作。我应该如何使用regex进行此操作

不带正则表达式的解决方案也很好。

例如

const char * demo = "FE2A8D0000CA372D4F461B1D9A1883A32F018823FFFF60D30000484200000D0A0F270300030006000000B0040307000356A3";
int len = strlen(demo);
int i;
char ** msg = (char**) malloc(sizeof(char*) * len / 2);
for(i = 0; i < len / 2; i++) {
    msg[i] = (char*) malloc(sizeof(char) * 5);
    strncpy(msg[i], "0x", 2);
    strncpy(msg[i] + 2, demo + i * 2, 2);
    strncpy(msg[i] + 4, "\0", 1);
}
const char*demo=“FE2A8D0000CA372D4F461B1D9A1883A32F018823FF60D300004844200000D0A0F27030000000B0040307000356A3”;
int len=strlen(演示);
int i;
char**msg=(char**)malloc(sizeof(char*)*len/2);
对于(i=0;i
以下代码可能满足要求:

 #include <stdio.h>
 #include <string.h>

 void printHex(char data[])
 {
     int i,j;
     char temp[] = "0x00";
     int count = strlen(data)/2;

     for(i=0, j=0; i<count;i++, j+=2)
     {
         temp[2] = data[j];
         temp[3] = data[j+1];
         printf("%s, ",temp);
     }
 }

 int main()
 {
     char data[]="FE2A8D0000CA372D4F461B1D9A1883A32F018823FFFF60D30000484200000D0A0F270300030006000000B0040307000356A3";
     printHex(data);
     return 0;
 }
#包括
#包括
void printHex(字符数据[])
{
int i,j;
字符温度[]=“0x00”;
整数计数=strlen(数据)/2;

对于(i=0,j=0;i您的问题有点不清楚,但假设您只想在运行时用十六进制字符串中的二进制数据填充
char
数组,类似这样的操作就可以了:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

const char *buf = "FE2A8D0000CA372D4F461B1D9A1883A32F018823FFFF60D30000484200000D0A0F270300030006000000B0040307000356A3";

static unsigned char hexNibble(const char *str)
{
    unsigned char hex = *str;
    if (hex >= 'a' && hex <='f')
    {
        hex -= ('a' - 10);
    }
    else if (hex >= 'A' && hex <= 'F')
    {
        hex -= ('A' - 10);
    }
    else if (hex >= '0' && hex <= '9')
    {
        hex -= '0';
    }
    else
    {
        hex = 0;
    }
    return hex;
}

static size_t createCharArrayFromHexString(char *result[], const char *str)
{
    size_t len = strlen(str);
    if (!len) return 0;
    size_t bytes = len / 2;
    int mostSignificantNibble = len % 2;
    size_t size = bytes + mostSignificantNibble;
    *result = malloc(size);
    char *out = *result;
    const char *in = str;
    if (mostSignificantNibble)
    {
        *out++ = hexNibble(in++);
    }
    while (bytes)
    {
        *out = hexNibble(in++);
        *out <<= 4;
        *out++ |= hexNibble(in++);
        --bytes;
    }
    return size;
}

int main(void) {
    int value = 0;
    char *converted;

    size_t convertedSize = createCharArrayFromHexString(&converted, buf);

    for (int i = 0; i < convertedSize; ++i)
    {
        printf( "0x%02hhx\n", converted[i]);
    }

    free(converted);
}
#包括
#包括
#包括
const char*buf=“FE2A8D0000CA372D4F461B1D9A1883A32F018823FF60D300004844200000D0A0F2703000000000B0040307000356A3”;
静态无符号字符HEXNIBLE(常量字符*str)
{
无符号字符十六进制=*str;

如果(hex>='a'&&hex='a'&&hex='0'&&hex,下面框中的程序包含函数
const char*convert(const char*inb,int idx)
,该函数创建一个缓冲区,其中包含按需要格式化的数据

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libgen.h>

#define STR_HELPER(x) #x
#define STR(x) STR_HELPER(x)
#define HEADER1_TEXT "const char msg_"

#define HEADER2_LEN     6   //The number of digits in the costants name msg_nnnn we want

#define HEADER3_TEXT "[] = {"
#define HEADERLENGTH   (strlen(HEADER1_TEXT)+HEADER2_LEN+strlen(HEADER3_TEXT))

#define FOOTER "\n};\n"
#define FOOTERLENGTH    (strlen(FOOTER))

#define INDENT "\n    "
#define INDENTLENGTH    (strlen(INDENT))

#define ITEMxROW        8
#define HEXFIELDLEN     6           // "0xnn, "
#define ROWLEN          (INDENTLENGTH + (ITEMxROW * HEXFIELDLEN))

const char * convert(const char * inb,int idx);

const char * convert(const char * inb,int idx)
{
    char * outb = NULL;
    unsigned int l,rl=0,j;

    l=strlen(inb);
    if (l) {
        j=l/2*HEXFIELDLEN - 1;      //The char used to convert all digit with the format: "0xnn, "
        rl=(j+ROWLEN)/ROWLEN;       //Row number
        j=j + rl*(INDENTLENGTH+1);  // +1 The CR
        j=j + HEADERLENGTH + FOOTERLENGTH;

        outb = malloc(j+11); //+ 11 because the dimension is not correctly computed!!! :(
        memset(outb,0,j+1);

        if (outb!=NULL) {
            strcpy(outb, HEADER1_TEXT);

            sprintf(outb+strlen(outb),"%0" STR(HEADER2_LEN) "d",idx);

            strcat(outb,HEADER3_TEXT);

            rl=0;
            for(j=0;j<l;j+=2) {
                if (j)
                    strcat(outb,", ");

                if ( (rl + HEADER2_LEN) > ROWLEN) {
                    rl=0;
                }

                if (!rl) {
                    rl=INDENTLENGTH;
                    strcat(outb,INDENT);
                }

                strcat(outb,"0x");
                strncat(outb,inb+j,2);

                rl+=HEXFIELDLEN;
            }
        }
    }

    return outb;
}

int main(int argc, char *argv[])
{
    int i,retval=0;
    char * buff=NULL;

    if (argc<2) {
        printf("Usage: %s hex-string [hex-string2] [...] [hex-stringn]\n",basename(argv[0]));
        return 1;
    }

    for(i=1; i<argc; i++) {
        buff=convert(argv[i],i);

        if (buff!=NULL) {
            strcat(buff,FOOTER);
            printf("%s\n",buff);
            free(buff);
        } else {
            retval=1;
            break;
        }
    }

    return retval;
}
输出将是:

const char msg_000001[] = {
    0xFE, 0x2A, 0x8D, 0x00, 0x00, 0xCA, 0x37, 0x2D, 
    0x4F, 0x46, 0x1B, 0x1D, 0x9A, 0x18, 0x83, 0xA3, 
    0x2F, 0x01, 0x88, 0x23, 0xFF, 0xFF, 0x60, 0xD3, 
    0x00, 0x00, 0x48, 0x42, 0x00, 0x00, 0x0D, 0x0A, 
    0x0F, 0x27, 0x03, 0x00, 0x03, 0x00, 0x06, 0x00, 
    0x00, 0x00, 0xB0, 0x04, 0x03, 0x07, 0x00, 0x03, 
    0x56, 0xA3
};
const char msg_000001[] = {
    0xFE, 0x55, 0xAC, 0xA2, 0x20
};

const char msg_000002[] = {
    0x56, 0xAB, 0xFC
};

const char msg_000003[] = {
    0x45, 0x87, 0xAB, 0xFD
};
您可以转换更多字符串。例如:

sysprompt: convert FE55ACA220 56ABFC 4587ABFD
输出将是:

const char msg_000001[] = {
    0xFE, 0x2A, 0x8D, 0x00, 0x00, 0xCA, 0x37, 0x2D, 
    0x4F, 0x46, 0x1B, 0x1D, 0x9A, 0x18, 0x83, 0xA3, 
    0x2F, 0x01, 0x88, 0x23, 0xFF, 0xFF, 0x60, 0xD3, 
    0x00, 0x00, 0x48, 0x42, 0x00, 0x00, 0x0D, 0x0A, 
    0x0F, 0x27, 0x03, 0x00, 0x03, 0x00, 0x06, 0x00, 
    0x00, 0x00, 0xB0, 0x04, 0x03, 0x07, 0x00, 0x03, 
    0x56, 0xA3
};
const char msg_000001[] = {
    0xFE, 0x55, 0xAC, 0xA2, 0x20
};

const char msg_000002[] = {
    0x56, 0xAB, 0xFC
};

const char msg_000003[] = {
    0x45, 0x87, 0xAB, 0xFD
};

注意:在convert函数中有一段代码,用于计算要使用(和分配)的缓冲区的维度用于转换。这段代码不完全正确,请执行我的命令!我想你可以解决这个问题!

在字符串上循环每两个字符并打印你需要的任何内容会更清晰,IMHObut print?我需要分离为字符数组。你可能会发现有用。对不起,我以为你在尝试编写一个t生成源代码。例如,您可以使用sscanf(buf+offset,“%x”,&value),然后在循环中使用offset+=2。然后将值放入数组中。可能的改进:避免使用
malloc
的结果,在为数组分配内存时使用
calloc
,将
demo+i
替换为
demo[i]
,在for循环中声明
i
,比如
for(int i=0…)
?当您将内存分配给数组时,为什么要使用
calloc
?是否可以将内存分配给非数组的其他对象?为什么要避免强制转换?请不要只说
void*
是自动执行的参数promoted@tilz0R1.好多了(事实上更好)使用
void printHex(char*data)
来代替
void printHex(char data[])
有什么具体原因吗?我认为这是一个编码风格的问题。它不会改变任何东西。是的,这就是为什么我说得更好:)如果是这样,我不同意你;)。通常,当人们在代码中遇到指针时会感到害怕。因此,我更倾向于消除它们:)。顺便说一句,它因人而异,如前所述:这是一个选择的问题。这不是真的:)使用空数组对人来说可能意味着不同的事情,而不是指针特定的。在这种情况下应该使用指针。这是可以理解的。