C에서 바이트 배열을 16 진수 문자열로 어떻게 변환합니까?


89

나는 가지고있다:

uint8 buf[] = {0, 1, 10, 11};

printf를 사용하여 문자열을 인쇄 할 수 있도록 바이트 배열을 문자열로 변환하고 싶습니다.

printf("%s\n", str);

및 get (콜론이 필요하지 않음) :

"00:01:0A:0B"

어떤 도움이라도 대단히 감사하겠습니다.


buf[i]에 캐스팅되어야합니다. unsigned char그렇지 않으면 다음 buf[i] > 127과 같은 경우 오버플로됩니다 .buf_ptr += sprintf(buf_ptr, "%02X", (unsigned char)buf[i]);
whatacold

답변:


93
printf("%02X:%02X:%02X:%02X", buf[0], buf[1], buf[2], buf[3]);

보다 일반적인 방법 :

int i;
for (i = 0; i < x; i++)
{
    if (i > 0) printf(":");
    printf("%02X", buf[i]);
}
printf("\n");

문자열에 연결하려면 몇 가지 방법이 있습니다. 아마도 문자열 끝에 포인터를두고 sprintf를 사용할 것입니다. 또한 배열의 크기를 추적하여 할당 된 공간보다 커지지 않도록해야합니다.

int i;
char* buf2 = stringbuf;
char* endofbuf = stringbuf + sizeof(stringbuf);
for (i = 0; i < x; i++)
{
    /* i use 5 here since we are going to add at most 
       3 chars, need a space for the end '\n' and need
       a null terminator */
    if (buf2 + 5 < endofbuf)
    {
        if (i > 0)
        {
            buf2 += sprintf(buf2, ":");
        }
        buf2 += sprintf(buf2, "%02X", buf[i]);
    }
}
buf2 += sprintf(buf2, "\n");

Mark 고마워요-제 문제는 좀 더 복잡합니다. 실제로 길이가 X 바이트 인 버퍼가 있습니다. X 바이트에 대해 이것을 수행하고 결과로 문자열을 갖는 일반적인 방법을 찾고 싶었습니다.
Steve Walsh

주어진 바이트 수를 처리하는 코드를 추가하기 위해 업데이트되었습니다. x가 길이라고 가정합니다.
Mark Synowiec 2011 년

Mark에게 다시 한 번 감사드립니다.하지만이 문제에 대해 가장 까다로운 점은 이것을 문자열로 인쇄하는 방법입니다.
Steve Walsh

5
printf("%02X", (unsigned char)buf[i]);서명되지 않은 문자에 대한 오버 플로우가 발생합니다 원래의 표기
easytiger

3
왜 안돼 printf("%02hhX", buf[i])?
Hintron

32

완전한 경우에는 무거운 라이브러리 함수를 호출하지 않고도 쉽게 수행 할 수 있습니다 (snprintf 없음, strcat 없음, memcpy 없음). libc를 사용할 수없는 마이크로 컨트롤러 나 OS 커널을 프로그래밍하는 경우 유용 할 수 있습니다.

Google에서 검색하면 비슷한 코드를 찾을 수 있습니다. 실제로 snprintf를 호출하는 것보다 훨씬 복잡하지 않고 훨씬 빠릅니다.

#include <stdio.h>

int main(){
    unsigned char buf[] = {0, 1, 10, 11};
    /* target buffer should be large enough */
    char str[12];

    unsigned char * pin = buf;
    const char * hex = "0123456789ABCDEF";
    char * pout = str;
    int i = 0;
    for(; i < sizeof(buf)-1; ++i){
        *pout++ = hex[(*pin>>4)&0xF];
        *pout++ = hex[(*pin++)&0xF];
        *pout++ = ':';
    }
    *pout++ = hex[(*pin>>4)&0xF];
    *pout++ = hex[(*pin)&0xF];
    *pout = 0;

    printf("%s\n", str);
}

여기에 약간 더 짧은 버전이 있습니다. 중간 인덱스 변수 i와 라스트 케이스 코드를 복제하는 것을 피할뿐입니다 (그러나 종료 문자는 두 번 작성됩니다).

#include <stdio.h>
int main(){
    unsigned char buf[] = {0, 1, 10, 11};
    /* target buffer should be large enough */
    char str[12];

    unsigned char * pin = buf;
    const char * hex = "0123456789ABCDEF";
    char * pout = str;
    for(; pin < buf+sizeof(buf); pout+=3, pin++){
        pout[0] = hex[(*pin>>4) & 0xF];
        pout[1] = hex[ *pin     & 0xF];
        pout[2] = ':';
    }
    pout[-1] = 0;

    printf("%s\n", str);
}

아래는 입력 버퍼의 크기를 알기 위해 "트릭"을 사용했다는 의견에 대한 답변을 제공하는 또 다른 버전입니다. 실제로 이것은 트릭이 아니라 필요한 입력 지식입니다 (변환하는 데이터의 크기를 알아야 함). 변환 코드를 별도의 함수로 추출하여이를 더 명확하게했습니다. 또한 대상 버퍼에 대한 경계 검사 코드를 추가했는데, 우리가 무엇을하고 있는지 안다면 실제로 필요하지 않습니다.

#include <stdio.h>

void tohex(unsigned char * in, size_t insz, char * out, size_t outsz)
{
    unsigned char * pin = in;
    const char * hex = "0123456789ABCDEF";
    char * pout = out;
    for(; pin < in+insz; pout +=3, pin++){
        pout[0] = hex[(*pin>>4) & 0xF];
        pout[1] = hex[ *pin     & 0xF];
        pout[2] = ':';
        if (pout + 3 - out > outsz){
            /* Better to truncate output string than overflow buffer */
            /* it would be still better to either return a status */
            /* or ensure the target buffer is large enough and it never happen */
            break;
        }
    }
    pout[-1] = 0;
}

int main(){
    enum {insz = 4, outsz = 3*insz};
    unsigned char buf[] = {0, 1, 10, 11};
    char str[outsz];
    tohex(buf, insz, str, outsz);
    printf("%s\n", str);
}

1
그것은 속임수가 아니라 단지 상수 일뿐입니다. 질문의 맥락에서 16 진수로 변환하려는 소스의 길이가 잘 알려져 있음이 분명합니다 (sizeof 대신 하드 코딩 된 4를 넣을 수 있음). 일반적으로 함수는 알려진 길이의 일부 입력에 대해 호출되어야하며 대상 버퍼에는 3 배 + 1 바이트를 사용할 수 있습니다. 이는 호출자가 확인해야하며 변환 기능이 해당 작업을 수행 할 이유가 없습니다. strlen () 호출은 경우에 따라 소스 크기를 찾는 방법 일 수 있지만 항상 그런 것은 아닙니다. 16 진수로 변환 할 숫자에 0이 있으면 어떻게됩니까?
kriss

여러분의 함수에서 영감을 받아 snprintf 등과 유사한 출력 버퍼에 기록 된 바이트 수를 반환하는 버전을 작성했습니다. gist.github.com/cellularmitosis/0d8c0abf7f8aa6a2dff3
Jason Pepas 2015-09-26

char str [sizeof (buf) * 3 + 1]을 사용하여 출력 버퍼를 올바른 크기로 자동으로 만들어야한다고 생각합니다.
Cecil Ward

또한 더 많은 const가 당신을 보호 할 것입니다. 예를 들어 "const unsigned char const * p"를 입력하면 입력 버퍼가 기록되지 않도록 할 수 있습니다. 하나는 주소 (또는 '포인터')를 상수 또는 변수로 만들고 다른 하나는 해당 주소의 메모리를 읽기 전용인지 여부를 지정합니다. 종종 포인터가 뒤섞이는 것을 막습니다. 또한 입력 및 출력을위한 버퍼와 포인터를 문서화하는 의미있는 이름을 갖는 것도 도움이 될 것입니다.
Cecil Ward

@Cecil War : 내 코드가 가짜가 아니라면 const를 사용하는 것은 포인터를 혼합하거나 입력과 출력에 동일한 포인터를 사용하는 것을 제외하고는 많이 보호하지 않습니다 (그래도 가능합니다). 그러나 컴파일러가 코드를 최적화하는데도 도움이됩니다. 더 나은 방법은 제한 키워드를 사용하는 것입니다 (C ++가 아닌 너무 나쁜 C99이지만 컴파일러 확장으로 존재하는 경우가 많습니다). 입력 버퍼 in와 출력 버퍼 를 호출하는 데 더 의미있는 것은 무엇입니까 out? 또한 출력 버퍼를 제공하는 대신 문자열을 사용하고 복사본을 반환하는 것을 선택할 수 있습니다. 현대 C ++ 최적화 프로그램에서는 크게 신경 쓰지 않아도됩니다.
kriss

15

다음은 훨씬 빠른 방법입니다.

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

unsigned char *     bin_to_strhex(const unsigned char *bin, unsigned int binsz,
                                  unsigned char **result)
{
  unsigned char     hex_str[]= "0123456789abcdef";
  unsigned int      i;

  if (!(*result = (unsigned char *)malloc(binsz * 2 + 1)))
    return (NULL);

  (*result)[binsz * 2] = 0;

  if (!binsz)
    return (NULL);

  for (i = 0; i < binsz; i++)
    {
      (*result)[i * 2 + 0] = hex_str[(bin[i] >> 4) & 0x0F];
      (*result)[i * 2 + 1] = hex_str[(bin[i]     ) & 0x0F];
    }
  return (*result);
}

int                 main()
{
  //the calling
  unsigned char     buf[] = {0,1,10,11};
  unsigned char *   result;

  printf("result : %s\n", bin_to_strhex((unsigned char *)buf, sizeof(buf), &result));
  free(result);

  return 0
}

3
이 코드에는 인쇄 할 수없는 이상한 입력에서만 나타나는 버그가 포함되어 있습니다 (수학적으로 무슨 일이 일어나는지 정확히 조사 할 시간이 없었습니다). 16 진수의 바이너리를 인코딩 해보면 ca9e3c972f1c5db40c0b4a66ab5bc1a20ca4457bdbe5e0f8925896d5ed37d726빠져 ÌaÌe3cÌ72f1c5dÌ40c0b4a66Ìb5bÌ1Ì20cÌ4457bÌbÌ5Ì0Ì8Ì258Ì6Ì5Ìd37Ì726나갈 것입니다. 이 문제를 해결하려면 hex_strfor 루프의 첫 번째 줄에 있는 비트를 (input[i] >> 4) & 0x0F@kriss의 답변과 같이 변경해야합니다 . 그러면 잘 작동합니다.
niemiro

버그-malloc () 실패를 확인하지 않습니다.
Cecil Ward

아무도 서명 된 문자 (미친 DEC PDP11 하드웨어 기능)의 위험을 원하지 않으므로 서명되지 않은 문자를 절대적으로 모든 곳에서 사용하는 것이 더 낫습니다. 그러면 서명 된 비교가 잘못되거나 서명 된 오른쪽 시프트가 값을 손상시킬 위험이 없습니다. 이 경우 공정하게 말하면 코드는 여기에서 당신을 보호하는 모든 곳에서 & 0x0F를 방어 적으로 수행합니다.
Cecil Ward

이 루틴의 목적을 위해 메모리를 읽기 전용으로 선언하려면 bin 입력 매개 변수가 const unsigned char const * bin이어야합니다.
Cecil Ward

1
피드백을 주셔서 감사합니다
Yannuth

14

비슷한 답변이 위에 이미 존재하므로 다음 코드 줄이 정확히 어떻게 작동하는지 설명하기 위해이 답변을 추가했습니다.

ptr += sprintf(ptr, "%02X", buf[i])

조용히 까다 롭고 이해하기 쉽지 않습니다. 아래 주석에 설명을 넣었습니다.

uint8 buf[] = {0, 1, 10, 11};

/* Allocate twice the number of bytes in the "buf" array because each byte would
 * be converted to two hex characters, also add an extra space for the terminating
 * null byte.
 * [size] is the size of the buf array */
char output[(size * 2) + 1];

/* pointer to the first item (0 index) of the output array */
char *ptr = &output[0];

int i;

for (i = 0; i < size; i++) {
    /* "sprintf" converts each byte in the "buf" array into a 2 hex string
     * characters appended with a null byte, for example 10 => "0A\0".
     *
     * This string would then be added to the output array starting from the
     * position pointed at by "ptr". For example if "ptr" is pointing at the 0
     * index then "0A\0" would be written as output[0] = '0', output[1] = 'A' and
     * output[2] = '\0'.
     *
     * "sprintf" returns the number of chars in its output excluding the null
     * byte, in our case this would be 2. So we move the "ptr" location two
     * steps ahead so that the next hex string would be written at the new
     * location, overriding the null byte from the previous hex string.
     *
     * We don't need to add a terminating null byte because it's been already 
     * added for us from the last hex string. */  
    ptr += sprintf(ptr, "%02X", buf[i]);
}

printf("%s\n", output);

훌륭한 논리. 이 도전에 대한 우아한 비 C ++ 문자열 답변을 한 시간 동안 찾고있었습니다!
Mark Terrill

6

약간 주제에서 벗어난 (표준 C가 아님) 다음을 추가하고 싶었지만 자주 찾고 있으며 첫 번째 검색 히트 중이 질문에 걸림돌이됩니다. Linux 커널 인쇄 함수 printk에는 단일 형식 지정자를 통해 "직접"배열 / 메모리 내용을 출력하기위한 형식 지정자가 있습니다.

https://www.kernel.org/doc/Documentation/printk-formats.txt

Raw buffer as a hex string:
    %*ph    00 01 02  ...  3f
    %*phC   00:01:02: ... :3f
    %*phD   00-01-02- ... -3f
    %*phN   000102 ... 3f

    For printing a small buffers (up to 64 bytes long) as a hex string with
    certain separator. For the larger buffers consider to use
    print_hex_dump(). 

... 그러나 이러한 형식 지정자는 표준 user-space에 대해 존재하지 않는 것 같습니다 (s)printf.


5

해결책

함수는 btox임의의 데이터 변환 *bb종결되지 않은 스트링 *xpn16 진수 :

void btox(char *xp, const char *bb, int n) 
{
    const char xx[]= "0123456789ABCDEF";
    while (--n >= 0) xp[n] = xx[(bb[n>>1] >> ((1 - (n&1)) << 2)) & 0xF];
}

#include <stdio.h>

typedef unsigned char uint8;

void main(void) 
{
    uint8 buf[] = {0, 1, 10, 11};
    int n = sizeof buf << 1;
    char hexstr[n + 1];

    btox(hexstr, buf, n);
    hexstr[n] = 0; /* Terminate! */
    printf("%s\n", hexstr);
}

결과 : 00010A0B.

라이브 : Tio.run .


1

다음은 변환을 수행하는 한 가지 방법입니다.

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

#define l_word 15
#define u_word 240

char *hex_str[]={"0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"};

main(int argc,char *argv[]) {


     char *str = malloc(50);
     char *tmp;
     char *tmp2;

     int i=0;


     while( i < (argc-1)) {
          tmp = hex_str[*(argv[i]) & l_word];
          tmp2 = hex_str[*(argv[i]) & u_word];

          if(i == 0) { memcpy(str,tmp2,1); strcat(str,tmp);}
          else { strcat(str,tmp2); strcat(str,tmp);}
          i++;
    }

    printf("\n*********  %s  *************** \n", str);

}

1

약간 수정 된 Yannith 버전. 나는 그것을 반환 값으로 갖고 싶습니다.

typedef struct {
   size_t len;
   uint8_t *bytes;
} vdata;

char* vdata_get_hex(const vdata data)
{
   char hex_str[]= "0123456789abcdef";

   char* out;
   out = (char *)malloc(data.len * 2 + 1);
   (out)[data.len * 2] = 0;
   
   if (!data.len) return NULL;
   
   for (size_t i = 0; i < data.len; i++) {
      (out)[i * 2 + 0] = hex_str[(data.bytes[i] >> 4) & 0x0F];
      (out)[i * 2 + 1] = hex_str[(data.bytes[i]     ) & 0x0F];
   }
   return out;
}


1

이 함수는 사용자 / 호출자가 16 진수 문자열을 문자 배열 / 버퍼에 넣기를 원하는 경우에 적합합니다. 문자 버퍼의 16 진수 문자열을 사용하면 사용자 / 호출자는 자체 매크로 / 기능을 사용하여 원하는 위치 (예 : 파일)에 표시하거나 기록 할 수 있습니다. 이 함수는 호출자가 각 줄에 넣을 (16 진수) 바이트 수를 제어 할 수도 있습니다.

/**
 * @fn 
 * get_hex
 *
 * @brief 
 * Converts a char into bunary string 
 *
 * @param[in]   
 *     buf Value to be converted to hex string
 * @param[in]   
 *     buf_len Length of the buffer
 * @param[in]   
 *     hex_ Pointer to space to put Hex string into
 * @param[in]   
 *     hex_len Length of the hex string space
 * @param[in]   
 *     num_col Number of columns in display hex string
 * @param[out]   
 *     hex_ Contains the hex string
 * @return  void
 */
static inline void
get_hex(char *buf, int buf_len, char* hex_, int hex_len, int num_col)
{
    int i;
#define ONE_BYTE_HEX_STRING_SIZE   3
  unsigned int byte_no = 0;

  if (buf_len <= 0) {
      if (hex_len > 0) {
        hex_[0] = '\0';
      }
      return;
  }

  if(hex_len < ONE_BYTE_HEX_STRING_SIZE + 1)
  {
      return;
  }

  do {
         for (i = 0; ((i < num_col) && (buf_len > 0) && (hex_len > 0)); ++i )
         {
            snprintf(hex_, hex_len, "%02X ", buf[byte_no++] & 0xff);
            hex_ += ONE_BYTE_HEX_STRING_SIZE;
            hex_len -=ONE_BYTE_HEX_STRING_SIZE;
            buf_len--;
         }
         if (buf_len > 1)
         {
             snprintf(hex_, hex_len, "\n");
             hex_ += 1;
         }
  } while ((buf_len) > 0 && (hex_len > 0));

}

예 : 코드

#define DATA_HEX_STR_LEN 5000
    char      data_hex_str[DATA_HEX_STR_LEN];

    get_hex(pkt, pkt_len, data_hex_str, DATA_HEX_STR_LEN, 16);
    //      ^^^^^^^^^^^^                                  ^^
    //      Input byte array                              Number of (hex) byte
    //      to be converted to hex string                 columns in hex string

    printf("pkt:\n%s",data_hex_str) 

산출

pkt:
BB 31 32 00 00 00 00 00 FF FF FF FF FF FF DE E5 
A8 E2 8E C1 08 06 00 01 08 00 06 04 00 01 DE E5 
A8 E2 8E C1 67 1E 5A 02 00 00 00 00 00 00 67 1E 
5A 01 

0

C에는 이것에 대한 기본 요소가 없습니다. 입력에 대해 충분히 긴 버퍼와 루프를 malloc (또는 아마도 alloca) 할 것입니다. 또한 C ++와 유사한 의미론 (구문이 아님)을 가진 동적 문자열 라이브러리로 수행되는 것을 보았습니다. 이것은 ostringstream그럴듯하게 더 일반적인 솔루션이지만 단일 사례에 대한 추가 복잡성의 가치가 없을 수도 있습니다.


0

16 진수 값을 char *문자열 에 저장 하려면 snprintf. 선행 0과 콜론을 포함하여 인쇄 된 모든 문자에 대해 공간을 할당해야합니다.

Mark의 대답에 확장 :

char str_buf* = malloc(3*X + 1);   // X is the number of bytes to be converted

int i;
for (i = 0; i < x; i++)
{
    if (i > 0) snprintf(str_buf, 1, ":");
    snprintf(str_buf, 2, "%02X", num_buf[i]);  // need 2 characters for a single hex value
}
snprintf(str_buf, 2, "\n\0"); // dont forget the NULL byte

이제 str_buf16 진수 문자열이 포함됩니다.


이것은 처음 2 개의 문자를 계속해서 덮어 씁니다 .. 맞죠?
xordon

0

콜론 구분 기호를 포함하도록 조정 된 ZincX의 솔루션 :

char buf[] = {0,1,10,11};
int i, size = sizeof(buf) / sizeof(char);
char *buf_str = (char*) malloc(3 * size), *buf_ptr = buf_str;
if (buf_str) {
  for (i = 0; i < size; i++)
    buf_ptr += sprintf(buf_ptr, i < size - 1 ? "%02X:" : "%02X\0", buf[i]);
  printf("%s\n", buf_str);
  free(buf_str);
}

0

관심있는 모든 분들을 위해 여기에 C ++ 버전을 추가하겠습니다 .

#include <iostream>
#include <iomanip>
inline void print_bytes(char const * buffer, std::size_t count, std::size_t bytes_per_line, std::ostream & out) {
    std::ios::fmtflags flags(out.flags()); // Save flags before manipulation.
    out << std::hex << std::setfill('0');
    out.setf(std::ios::uppercase);
    for (std::size_t i = 0; i != count; ++i) {
        auto current_byte_number = static_cast<unsigned int>(static_cast<unsigned char>(buffer[i]));
        out << std::setw(2) << current_byte_number;
        bool is_end_of_line = (bytes_per_line != 0) && ((i + 1 == count) || ((i + 1) % bytes_per_line == 0));
        out << (is_end_of_line ? '\n' : ' ');
    }
    out.flush();
    out.flags(flags); // Restore original flags.
}

그것은의 16 진 덤프 인쇄 할 buffer길이를 count위해 std::ostream out(당신이 기본적 할 수 있습니다 std::cout). 모든 행에는 bytes_per_line바이트 가 포함 되며 각 바이트는 대문자 2 자리 16 진수로 표시됩니다. 바이트 사이에 공백이 있습니다. 그리고 줄 끝이나 버퍼 끝에서 줄 바꿈을 인쇄합니다. bytes_per_line가 0으로 설정 되면 new_line을 인쇄하지 않습니다. 스스로 시도하십시오.


0

간단한 사용법을 위해 입력 문자열 (이진 데이터)을 인코딩하는 함수를 만들었습니다.

/* Encodes string to hexadecimal string reprsentation
    Allocates a new memory for supplied lpszOut that needs to be deleted after use
    Fills the supplied lpszOut with hexadecimal representation of the input
    */
void StringToHex(unsigned char *szInput, size_t size_szInput, char **lpszOut)
{
    unsigned char *pin = szInput;
    const char *hex = "0123456789ABCDEF";
    size_t outSize = size_szInput * 2 + 2;
    *lpszOut = new char[outSize];
    char *pout = *lpszOut;
    for (; pin < szInput + size_szInput; pout += 2, pin++)
    {
        pout[0] = hex[(*pin >> 4) & 0xF];
        pout[1] = hex[*pin & 0xF];
    }
    pout[0] = 0;
}

용법:

unsigned char input[] = "This is a very long string that I want to encode";
char *szHexEncoded = NULL;
StringToHex(input, strlen((const char *)input), &szHexEncoded);

printf(szHexEncoded);

// The allocated memory needs to be deleted after usage
delete[] szHexEncoded;

0

Yannuth의 답변을 기반으로 하지만 단순화되었습니다.

여기서의 길이는의 dest[]두 배임을 의미 len하며 할당은 호출자가 관리합니다.

void create_hex_string_implied(const unsigned char *src, size_t len, unsigned char *dest)
{
    static const unsigned char table[] = "0123456789abcdef";

    for (; len > 0; --len)
    {
        unsigned char c = *src++;
        *dest++ = table[c >> 4];
        *dest++ = table[c & 0x0f];
    }
}

0

이 질문에 이미 답이 있다는 것을 알고 있지만 내 솔루션이 누군가를 도울 수 있다고 생각합니다.

그래서 제 경우에는 키를 나타내는 바이트 배열이 있었고 한 줄로 출력하기 위해이 바이트 배열을 16 진수 값의 char 배열로 변환해야했습니다. 다음과 같은 함수로 코드를 추출했습니다.

char const * keyToStr(uint8_t const *key)
{
    uint8_t offset = 0;
    static char keyStr[2 * KEY_SIZE + 1];

    for (size_t i = 0; i < KEY_SIZE; i++)
    {
        offset += sprintf(keyStr + offset, "%02X", key[i]);
    }
    sprintf(keyStr + offset, "%c", '\0');

    return keyStr;
}

이제 다음과 같이 내 기능을 사용할 수 있습니다.

Serial.print("Public key: ");
Serial.println(keyToStr(m_publicKey));

Serial객체는 Arduino 라이브러리의 일부이며 m_publicKey다음 선언으로 내 클래스의 구성원입니다 uint8_t m_publicKey[32].


0

snprintf 및 malloc으로 해결할 수 있습니다.

char c_buff[50];

u8_number_val[] = { 0xbb, 0xcc, 0xdd, 0x0f, 0xef, 0x0f, 0x0e, 0x0d, 0x0c };

char *s_temp = malloc(u8_size * 2 + 1);

for (uint8_t i = 0; i < u8_size; i++)
{
    snprintf(s_temp  + i * 2, 3, "%02x", u8_number_val[i]);
}

snprintf(c_buff, strlen(s_temp)+1, "%s", s_temp );

printf("%s\n",c_buff);

free(s);

출력 : bbccdd0fef0f0e0d0c


-2

얼마나 복잡한 솔루션입니까!
Malloc과 스프린트와 캐스트 오 마이. (OZ 인용문)
어디에도 단일 rem이 아닙니다. 아이쿠

어떻게 이런 일에 대해?

main()
{
    // the value
    int value = 16;

    // create a string array with a '\0' ending ie. 0,0,0
    char hex[]= {0,0,'\0'}; 
    char *hex_p=hex;

    //a working variable
    int TEMP_int=0;

    // get me how many 16s are in this code
    TEMP_int=value/16;

    // load the first character up with 
    // 48+0 gives you ascii 0, 55+10 gives you ascii A
    if (TEMP_int<10) {*hex_p=48+TEMP_int;}
        else {*hex_p=55+TEMP_int;}

    // move that pointer to the next (less significant byte)<BR>
    hex_p++;

    // get me the remainder after I have divied by 16
    TEMP_int=value%16;

    // 48+0 gives you ascii 0, 55+10 gives you ascii A
    if (TEMP_int<10) {*hex_p=48+TEMP_int;}
        else {*hex_p=55+TEMP_int;}

    // print the result
    printf("%i , 0x%s",value,hex);

}

이제 두 개의 16 진수가 있습니다. 구분 기호를 추가하고 변환 할 다른 바이트를 처리해야합니다. 루프로? 그것을 함수로 만들면 저와 비슷한 것을 갖게 될 것입니다 (하지만 장황하고 읽기 어렵습니다). 다른 포스터에 이름을 붙이기 전에 적어도 일을 끝내야할까요?
kriss 2015 년

1
그리고 소스 코드의 주석에 대한 한 마디 (REM이 아니라 주석에 대한 BASIC 키워드이므로 피하십시오) : 코드가 수행하는 작업을 영어로 말하는 주석은 매우 나쁜 습관입니다! 그렇습니다. 프로그래머는 모듈로 연산자가 의미하는 바를 알고 있어야하며 (유물을줍니다) 그 나눗셈은 숫자가 다른 숫자에 나타나는 횟수를 계산하고 그 결과를 printf 인쇄합니다. 어머!
kriss
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.