【C言語/C++】文字列を16進数に変換

C言語/C++

今回の記事内容は文字列を16進数に変換する方法です。
毎回忘れてしまってたまにプログラムを書く時にどうするんだっけ、、、?となるのでメモします。

参考になる人

▶ C言語で文字(char型)を数値に変換したい人
▶ C言語で文字列(char配列)2yteを数値に変換したい人
 リトルエンディアン、ビッグエンディアンの変換方法

では、さっそくいくつかの方法を順番に確認します。

sscanf()を使う方法。

これはよく使います、さくっと変換したいとき、自作で変換関数作るのめんどくさいってなったときに結構便利です。(笑)
さっそくサンプルです。

int main() {

    // 読み込むcharデータ
    char readbyte[1] = {'1'};

    int a;
    sscanf(&readbyte[0], "%x", &b);
    printf("%d\n", a);
}

上記のように通常は問題なく使用できます。ですが、使えない場面があります。

【補足】VisualC++では使えない

WindowsでVisualStdioを使っているときです。
VisualC++でsscanf()を使って文字列を16進数に変換し用とした場合は使えません。
エラーではないが、警告が表示されてビルドできません。C4996エラー

次はVisualC++でも使える方法を紹介します。

自作関数を用意する

まぁ他にも変換する方法はあるとは思いますが、とりあえず自作関数を用意しましょうということで以下です。
まずは、1文字の変換を行うtoHex(char byte)から確認

2-1.int toHex(char byte)・・・1文字変換

まずはソースコードです。

#include <stdio.h>

int toHex(char byte){
    // 0~9がセットされた場合
    if ('0' <= byte && byte <= '9') {
        return byte - '0';
    }
    // a~fがセットされた場合
    else if ('a' <= byte && byte <= 'f') {
        return byte - 'a';
    }
    // A~Fがセットされた場合
    else if ('A' <= byte && byte <= 'F') {
        return byte - 'A';
    }
    // 上記以外の場合は変換エラーとして-1を返却する.
    else {
        return -1;
    }
}
/********************************/
/* メイン処理   
/********************************/
int main() {

    // 読み込むcharデータ
    char readbyte[1] = {'1'};  // '1' -> 1(10)

    int b;

    int a = toHex(readbyte[0]);
    printf("%d\n", a);
}
/********************************************/
/* 実行結果:1                               */
/********************************************/

これだと1文字変換に対応できます。
次はtoHex()を応用して2文字変換に対応させてみましょう。

2-2.toDHex(char * arrayBytes)

先程、紹介したtoHex()関数を使って、2バイト分の変換(範囲は0 ~ 255)をまとめて行います。

/********************************/
/* 2文字分を16進数に変換(0 ~ 255)
/********************************/
int toDHex(char* arrayBytes) {
	return toHex(arrayBytes[1]) * 0x01 + toHex(arrayBytes[0]) * 0x10;
}

/********************************/
/* メイン処理   
/********************************/
int main() {

    // 読み込むcharデータ
    char readbyte1[2] = {'1', '0' };  //10 -> 16(10)
	char readbyte2[2] = {'1', 'F' };
	char readbyte3[2] = {'F', 'F'};
	
	int num1 = toDHex(&readbyte1[0]);
	int num2 = toDHex(&readbyte2[0]);
	int num3 = toDHex(&readbyte3[0]);
    printf("num1:%d\n", num1);
    printf("num2:%d\n", num2);
    printf("num3:%d\n", num3);
}
/********************************************/
/* 実行結果:                               
/* num1:16
/* num2:31
/* num3:255
/********************************************/

上記ソースコードは正常な文字がchar[]にセットされることを前提で書いています。
実際に利用する場合には、事前チェックなどの処理はいれてあげる必要があります。

リトルエンディアン,ビックエンディアンにも対応可能

byteデータを読み込むときはその環境によってバイトを読み込み方に違いがあります。
「ビックエンディアン」か「リトルエンディアン」かですね。
でが順番にそれぞれ確認していきます。

ビックエンディアン

ビッグエンディアンとは「最上位バイトから下位バイトに向けて記録・送信する方式
こちらはこれまで通りですね。

/********************************/
/* ビックエンディアンで2バイト文字を数値に変換 
/********************************/
int toDhex_bigE(char* arrayByte) {
    return toHex(arrayByte[0]) * 0x10 + toHex(arrayByte[1]) * 0x01;
}
/********************************/
/* メイン処理   
/********************************/
int main() {

    // 読み込むcharデータ
        // 読み込むcharデータ
    char readbyte1[2] = {'1', '0' };  //10 -> 16(10)
	char readbyte2[2] = {'1', 'F' };
	char readbyte3[2] = {'F', 'F'};
	
	int num1 = toDhex_bigE(&readbyte1[0]);
	int num2 = toDhex_bigE(&readbyte2[0]);
	int num3 = toDhex_bigE(&readbyte3[0]);
    printf("num1:%d\n", num1);
    printf("num2:%d\n", num2);
    printf("num3:%d\n", num3);
}

リトルエンディアン

リトルエンディアンとは「最下位バイトから上位バイトに向けて記録・送信する方式

こちらは読み込むバイトの順番が反対になりますね。
なので以下のように読み込む配列のインデックスをビックエンディアンとは反対にします。

/********************************/
/* リトルエンディアンで2バイト文字を数値に変換 
/********************************/
int toDhex_littleE(char* arrayByte) {
    return toHex(arrayByte[1]) * 0x01 + toHex(arrayByte[0]) * 0x10;
}
/********************************/
/* メイン処理   
/********************************/
int main() {

    // 読み込むcharデータ
        // 読み込むcharデータ
    char readbyte1[2] = {'1', '0' };  //10 -> 16(10)
	char readbyte2[2] = {'1', 'F' };
	char readbyte3[2] = {'F', 'F'};

    int num1 = toDhex_littleE(&readbyte1[0]);
    int num2 = toDhex_littleE(&readbyte2[0]);
	int num3 = toDhex_littleE(&readbyte3[0]);
    printf("num1:%d\n", num1);
    printf("num2:%d\n", num2);
    printf("num3:%d\n", num3);
}

まとめ

できれば、sscanf()で変換できれば楽ですね〜、、、笑

コメント

タイトルとURLをコピーしました