我有一个包含十六进制字符(不包含0x
或\x
的char字符串):
char *A = "0a0b0c";
我想从中获得的
const char *B = "\x0a\x0b\x0c";
是否有一种有效的方法来做到这一点?谢谢!
编辑:为了清楚起见,我希望结果字符串包含3个字符\x0a
,\x0b
,\x0c
,而不是包含"\x0a\x0b\x0c"
的12个字符串\
和x
被读取为单独的字符。
这是我尝试过的:
const char *B[12];
for (j = 0; j < 4; ++j) {
B[4 * j + 0] = '\\';
B[4 * j + 1] = 'x';
B[4 * j + 2] = A[2 * j];
B[4 * j + 3] = A[2 * j + 1];
};
B[12] = '\0';
这给了我12个字符串"\x0a\x0b\x0c"
,但是我希望B
像这样分配:
const char *B = "\x0a\x0b\x0c";
答案 0 :(得分:0)
您可以编写一个将所需的sprintf转换为字符串,然后将其与目标字符串连接的函数。
类似的事情...
#include <stdio.h>
#include <string.h>
void createB (char B[10], const char *start)
{
char temp[10];
sprintf(temp, "\\x%c%c", start[0], start[1]);
strcat(B, temp);
}
int main ()
{
char A[] = "0a0b0c";
char B[10] = {'\0'};
for (int i=0; A[i] != '\0'; i = i+2)
{
createB(B, A+i);
}
printf("%s\n", B);
return 0;
}
$ ./main.out
\x0a\x0b\x0c
您可以对其进行修改以适合您的需求,或者使其具有更高的效率。
请根据需要进行编辑;通过必要的检查使其更安全。我刚刚提供了一个可行的逻辑。
答案 1 :(得分:0)
根据kiran的建议,虽然使用char A[] = "0a0b0c";
可以更改字符串,但仍不允许插入字符。因为那样会使字符串更长,因此不适合可用内存。如果您无法立即以所需的大小创建目标字符串,这又是一个问题。
如果输入始终具有相同的长度并且始终需要相同数量的插入字符,例如,可以预先知道所需的大小。如果像您的示例中那样,目标字符串是输入字符串大小的两倍。对于简单的字符数组定义,您需要在编译时已经知道大小。
char A[7] = "0a0b0c"; /* not 6, because size for the termianting \0 is needed */
char B[13] = ""; /* 2*6+1 */
因此,您可以使用char * A =“ 0a0b0c”;通过设置适当大小的内存作为目标,可以使您的生活更轻松。为此,您需要首先确定所需内存的长度,然后分配它。
确定大小(如果容易),如果您知道它将是输入大小的两倍。
/* inside a function, this does not work as a variable definition */
int iLengthB = 2*length(A);
char* B = malloc(iLengthB+1); /* mind the terminator */
然后在A上循环,将每两个字符复制到B,并在其前面加上两个字符“ \ x”。我认为这部分对您来说很明显。否则,请说明如何如上所述设置程序,并进行循环以分别输出A中的每个字符。然后,在您证明了自己的努力之后,我可以提供更多帮助。
答案 2 :(得分:0)
如果您只想在 string-literal "\x"
中的每个'0'
之前添加A
,并在结果中添加一个新字符串B
,那么就需要一个简单而直接的循环,并且B
中的存储足以处理"\x"
中每个'0'
的{{1}}的加法。
例如:
A
您不能简单地将#include <stdio.h>
#define MAXC 32
int main (void) {
char *A = "0a0b0c",
*pa = A,
B[MAXC],
*pb = B;
do { /* loop over all chars in A */
if (*pa && *pa == '0') { /* if chars remain && char is '0' */
*pb++ = '\\'; /* write '\' to B, adv ptr */
*pb++ = 'x'; /* write 'x' to B, adv ptr */
}
*pb++ = *pa; /* write char from A, adv ptr */
} while (*pa++); /* while chars remain (writes nul-termining char) */
puts (B); /* output result */
}
更改为带有A
的数组,然后写回char A[] = 0a0b0c";
,因为A
中没有足够的空间来处理字符加法。您总是可以声明A
足够大,然后每次添加A
时将字符向右移动两个,但是将结果写入新字符串更有意义。
使用/输出示例
"\x"
如果您需要其他帮助,请告诉我,我们很乐意进一步提供帮助。这可能是处理所需字符序列的更直接方法之一。
答案 3 :(得分:0)
#include <stdio.h>
int main(void)
{
char str1[] = "0a0b0c";
char str2[1000];
int i, j;
i = j = 0;
printf("sizeof str1 is %d.\n", sizeof(str1)-1);
for(i = 0; i < sizeof(str1)-1; i += 2)
{
str2[j] = '\\';
str2[j+1] = 'x';
str2[j+2] = str1[i];
str2[j+3] = str1[i+1];
j+=4;
}
str2[j] = '\0';
printf("%s\n", str2);
return 0;
}
我认为您可以这样做。
答案 4 :(得分:0)
假设没有错误的输入,假设“ a”至“ f”是按顺序排列的,假设没有大写字母:
// remember to #include <ctype.h>
char *input = "0a0b0c";
char *p = input;
while (*p) {
v = (isdigit((unsigned char)*p) ? *p-'0' : *p-'a'+10) * 16;
p++;
v += isdigit((unsigned char)*p) ? *p-'0' : *p-'a'+10;
p++;
printf("0x%d", v); // use v
}
答案 5 :(得分:0)
您的代码中存在多个困惑:
const char B[3];
或const char B[4];
。const char *B[12];
定义了一个由12个指向字符串的指针组成的数组,这是一个非常不同的野兽。for
很好,但是它根本不能满足您的要求。您想将十六进制编码值转换为字节值,而不要插入额外的\
和x
字符。;
之后的}
没用B[12]
处设置了一个空终止符,该终止符超出了B
的结尾。以下是使用sscanf
的更正版本:
const char *A = "0a0b0c";
const char B[4] = { 0 };
for (j = 0; j < 3; j++) {
sscanf(&A[j * 2], "%2hhx", (unsigned char *)&B[j]);
}
转换格式%2hhx
表示最多将A[j * 2]
的前2个字节转换为以十六进制编码的无符号整数,并将结果值存储到unsigned char
的{{1}}中。强制转换仅是为了避免编译器警告。