我正在开发一个串行通信程序,以在主机PC(Linux)和微控制器之间发送和接收数据。现在,我必须将十六进制数据发送到MCU。 因此,如何在不使用sprint / printf的情况下将缓冲区字符串数据转换为十六进制字符串,以便用户将诸如“ AA12CDFF1000001201”之类的字符串而不是“ \ xAA \ x12 \ xCD \ xFF \ x10 \ x00 \ x00 \ x00 \ x12 \ x01”发送到MCU。我也看到了Sending Hexadecimal to Serial Port,但是它没有帮助,因为它说我可以使用sprintf将字符串转换为十六进制,但是在这种情况下,我不想使用sprinf。 基本上我想要的是: 如果用户给定输入=“ AA12CDFF1000001201”,我必须将其转换为以下格式“ \ xAA \ x12 \ xCD \ xFF \ x10 \ x00 \ x00 \ x00 \ x12 \ x01”,然后将其写入串行端口。
#include <stdio.h> /* Standard input/output definitions */
#include <string.h> /* String function definitions */
#include <unistd.h> /* UNIX standard function definitions */
#include <fcntl.h> /* File control definitions */
#include <errno.h> /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */
void main()
{
int fd;
fd = open("/dev/ttyf1", O_RDWR | O_NOCTTY | O_NDELAY);
char buff[]="\xAA\x12\xCD\xFF\x10\x00\x00\x12\x01";
write(fd, buff, sizeof(buff));
close(fd);
}
答案 0 :(得分:1)
在与Hessam和Arkku进行了全面的讨论之后,新版本的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* str2hexstr(char* inbuff) {
char *outbuff;
if (strlen(inbuff)%2) {
outbuff=malloc((strlen(inbuff)*2+3)*sizeof(char));
outbuff[strlen(inbuff)*2+2]='\0'; }
else {
outbuff=malloc(strlen(inbuff)*2+1*sizeof(char));
outbuff[strlen(inbuff)*2]='\0'; }
for (int strin=0,strout=0;strin<strlen(inbuff);) {
outbuff[strout++]='\\';
outbuff[strout++]='x';
outbuff[strout++]=(!strin&&strlen(inbuff)%2)?'0':inbuff[strin++];
outbuff[strout++]=inbuff[strin++];
}
return(outbuff);
}
int main()
{
char inbuff1[]="123",inbuff2[]="1234";
char *outbuff;
outbuff=str2hexstr(inbuff1);
printf("%s\n",outbuff);
free(outbuff);
outbuff=str2hexstr(inbuff2);
printf("%s\n",outbuff);
free(outbuff);
return 0;
}
答案 1 :(得分:0)
#include <stdio.h>
#include <string.h>
#include <stdint.h>
/* Dummy input */
char input[] = "11121314151617181920";
uint8_t output[32];
/* Convert input char to int */
uint8_t
char2byte(char c) {
if (c >= '0' && c <= '9') {
return c - '0';
} else if (c >= 'A' && c <= 'F') {
return c - 'A' + 10;
} else if (c >= 'a' && c <= 'f') {
return c - 'a' + 10;
}
return 0;
}
int
main() {
size_t len;
/* String must be even */
len = strlen(input);
if (len & 1 == 0) {
}
/* Process all inputs, 2 chars for single byte */
for (size_t i = 0; i < len / 2; ++i) {
output[i] = char2byte(input[2 * i]) << 4;
output[i] |= char2byte(input[2 * i + 1]);
}
/* Test, expected is 0x13 */
printf("Test output[2] = %02X\r\n", (unsigned)output[2]);
return 0;
}
如果运行代码:Test output[2] = 13
类似这样的事情。目标是将每个字节的每个半字节转换为char。这意味着输出长度是初始缓冲区大小的两倍。
#include <stdio.h>
#include <string.h>
#include <stdint.h>
/* Output array */
char output[128];
/* Dummy input data array */
char data[] = {0x12, 0x13, 0x14, 0x00, 0x5A};
/* Convert each nibble to char */
char num2char(uint8_t num) {
if (num < 10) {
return num + '0';
} else if (num < 16) {
return num - 10 + 'A';
}
}
int
main() {
size_t i;
printf("Hello World\r\n");
/* Process all bytes */
for (i = 0; i < sizeof(data) / sizeof(data[0]); i++) {
/* Generate it twice, for high and low nibble */
output[2 * i] = num2char((data[i] >> 4) & 0x0F);
output[2 * i + 1] = num2char((data[i]) & 0x0F);
}
/* Trailing zero for string */
output[2 * i] = 0;
printf("Output: %s\r\n", output);
return 0;
}
运行代码时:
Output: 121314005A
答案 2 :(得分:0)
看看这个,不是一个干净的代码,但是应该做的
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void hexify(const char *input, char *output)
{
int i = 0;
int o = 0;
while(1)
{
if(input[i] == 0) break;
output[o++] = '\\';
output[o++] = 'x';
output[o++] = input[i++];
if(input[i] == 0) break;
output[o++] = input[i++];
}
output[o] = 0;
}
int main()
{
char test[]="112233AA"; //user input
if((strlen(test) % 2) && strlen(test) != 1)
printf("Input is not in correct format");
else
{
char *out = malloc(2 * strlen(test) + 1);
hexify(test, out);
printf("%s", out);
free(out);//dont forget this
}
return 0;
}
答案 3 :(得分:0)
您想要这样的东西吗?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char inbuff[]="AA12CDFF1000001201";
char *outbuff;
if (strlen(inbuff)%2) {
printf("error : strlen is odd");
exit(1);}
outbuff=malloc((strlen(inbuff)*2+1)*sizeof(char));
for (int strin=0,strout=0;strin<strlen(inbuff);) {
outbuff[strout++]='\\';
outbuff[strout++]='x';
outbuff[strout++]=inbuff[strin++];
outbuff[strout++]=inbuff[strin++];
}
outbuff[strlen(inbuff)*2]='\0';
printf("%s\n",outbuff);
return 0;
}
答案 4 :(得分:0)
如何将我的缓冲区字符串数据转换为十六进制字符串....因此用户发送...?
给定输入=“ AA12CDFF1000001201”,我必须将其转换为以下格式“ \ xAA \ x12 \ xCD \ xFF \ x10 \ x00 \ x00 \ x12 \ x01”,然后将其写入串行端口。
当不需要中间存储到缓冲区时,这非常简单。
一次将原始 string 的2个字符 1 转换为一个字节,每次迭代写入每个字节。
#include <ctype.h>
void write_hex_string(const char *hs) {
while (isxdigit(hs[0]) && isxdigit(hs[1])) {
char buf[3] = { hs[0], hs[1], '\0' };
unsigned char value = (unsigned char) strtol(buf, 0, 16);
write(fd, &value, sizeof value);
hs += 2;
}
}
样品使用
write_hex_string("AA12CDFF1000001201");
如果代码可以在过程中更改原始的 string ,那么生活也很容易。因为有一个方便的位置来存储转换。
void write_hex_string(char *hs) {
char *pair = hs;
size_t length = 0;
while (isxdigit(pair[0]) && isxdigit(pair[1])) {
char buf[3] = { pair[0], pair[1], '\0' };
hs[length++] = (unsigned char) strtol(buf, 0, 16);
pair += 2;
}
write(fd, hs, length);
}
1 ,只要两个字符都是十六进制数字:['0'-'9','A'-'F','a'-'f']。