如何在C中将整数转换为Unicode字符串?

如何在C中将整数转换为Unicode字符串?,c,unicode,character-encoding,serial-number,C,Unicode,Character Encoding,Serial Number,我正在为一个嵌入式USB项目的固件工作。我想使用的生产程序员会自动将序列号写入指定内存地址的设备闪存中。程序员将序列号存储为十六进制数字,以指定的字节数表示。例如,如果我告诉它将序列号123456存储在地址0x3C00处,我的内存如下所示: 0x3C00 - 00 0x3C01 - 01 0x3C02 - E2 0x3C03 - 40 //(123456 in Hex = 1E240) wchar_t buf[10]; swprintf(buf, L"%d", your_int

我正在为一个嵌入式USB项目的固件工作。我想使用的生产程序员会自动将序列号写入指定内存地址的设备闪存中。程序员将序列号存储为十六进制数字,以指定的字节数表示。例如,如果我告诉它将序列号123456存储在地址0x3C00处,我的内存如下所示:

0x3C00  -  00
0x3C01  -  01
0x3C02  -  E2
0x3C03  -  40
//(123456 in Hex = 1E240)
wchar_t buf[10];
swprintf(buf, L"%d", your_int_value);
问题是,当我的主机应用程序从设备读取序列号时,它正在查找unicode字符数组。所以我的序列号应该是

{ '1','0',
  '2','0',
  '3','0',
  '4','0',
  '5','0',
  '6','0'}


因此,在我用C编写的固件中,是否可以从闪存中检索十六进制序列号,将其编码为unicode字符数组,并将其存储在Ram中的变量中?

您应该能够使用类似以下内容:

0x3C00  -  00
0x3C01  -  01
0x3C02  -  E2
0x3C03  -  40
//(123456 in Hex = 1E240)
wchar_t buf[10];
swprintf(buf, L"%d", your_int_value);
根据您对C运行时库的具体实现,细节可能会有所不同。例如,您的
swprintf()
可能需要
buf
中的字符数:

swprintf(buf, sizeof(buf)/sizeof(buf[0]), L"%d", your_int_value);

看起来你想要:

wsprintf(wchar_buffer, L"%d", serial_number)

(假设您的序列号适合32位整数。在任何情况下,
wsprintf
都会将您的序列号打印为wchar(unicode)字符串。

不确定此代码是否适合您的设备,但让我们试试

char buffer[MAX_SIZE];
char unicodeBuffer[MAX_SIZE];
sprintf(buffer, "%d", i);
int len = strlen(buffer);
int i = 0;
for (int i = 0; i <= (len << 1) - 2; i++)
   unicodeBuffer[i] = i % 2 ? buffer[i] : 0;
unicodeBuffer[i + 1] = 0;
unicodeBuffer[i + 2] = 0;
char缓冲区[MAX_SIZE];
炭纤维[最大尺寸];
sprintf(缓冲区,“%d”,i);
int len=strlen(缓冲区);
int i=0;

对于(int i=0;i如果序列号适合32位,并且平台是big-endian,并且支持Unicode、32位int和标准C库,那么这是非常简单的,正如其他答案所示。如果平台有32位int和8位chars,但是是小endian和/或不支持Unicode,并且序列号可以变化在篇幅上,下面的内容可能会有用,尽管有点技巧

void extract_serial_number(unsigned char* address, unsigned int bytes, char* buffer) {
    unsigned int value = 0;
    char c, *start = buffer;
    while (bytes--) {                      /* read the serial number into an integer */
        value = value << 8;
        value |= *address++;
    }
    while (value > 0) {                    /* convert to 16 bit Unicode (reversed) */
        *buffer++ = '0' + value % 10;
        *buffer++ = '\0';
        value /= 10;
    }
    *buffer++ = '\0';
    *buffer++ = '\0';
    buffer -= 4;
    while (buffer > start) {               /* reverse the string */
        c = *buffer;
        *buffer = *start;
        *start = c;
        buffer -= 2;
        start += 2;
    }
}
void extract\u serial\u number(无符号字符*地址、无符号整数字节、字符*缓冲区){
无符号整数值=0;
字符c,*start=buffer;
而(字节--){/*将序列号读入整数*/
值=值0){/*转换为16位Unicode(反向)*/
*缓冲区+='0'+值%10;
*缓冲区+='\0';
数值/=10;
}
*缓冲区+='\0';
*缓冲区+='\0';
缓冲区-=4;
while(buffer>start){/*反转字符串*/
c=*缓冲区;
*缓冲区=*开始;
*开始=c;
缓冲区-=2;
启动+=2;
}
}

如果您可以在嵌入式环境中访问
sprintf
,那么这应该可以:

#define MAX_SIZE(type) ((CHAR_BIT * sizeof(type) - 1) / 3 + 2)

/* Destination UCS2 buffer size must be at least 2*MAX_SIZE(int) */
void int_to_ucs2(char *dest, int q)
{
    char buffer[MAX_SIZE(q)];
    char *src = buffer;

    sprintf(buffer, "%d", q);

    do {
        *dest++ = *src;
        *dest++ = 0;
    } while (*src++);
}

我怀疑这在固件中是可能的,因为它是一个32位的数字,您必须使用%ld而不是%d。@Andrey:固件只是另一个名称的软件。固件可以有大量的运行时库。@semaj:
%d
适用于
int
类型的值,它与整数中的位数无关。
%ld
将适用于
long
类型的值。好吧,固件是在资源非常有限的设备上运行的软件,这些设备内存小,进程慢。而且编译器是特殊的。没有人会链接unicode libs只是为了向数组添加几个零。我认为示例数组应该读取
ushort[]serial={'1','2','3','4','5','6'}
我们可以假设您的C编译器理解unicode吗?
wchar\u t
不一定是16位UCS2(甚至不一定是unicode).True,但如果是这种情况,则会出现更大的问题。您应该能够阅读编译器的文档,以确定
wchar\u t
是否具有所需的字符大小(如果没有,则如何设置标志,以便
wchar\u t
满足您的需要)。你能解释一下L是什么意思吗?@SeanLetendre它意味着字符串文字应该被解释为“宽字符”(16位字符)字符串。这不起作用-它只是从sprintf
创建的缓冲区复制了一半字符。