掲示板利用宣言

 次のフォームをすべてチェックしてからご利用ください。

 私は

 題名と投稿者名は具体的に書きます。
 課題の丸投げはしません。
 ソースの添付は「HTML変換ツール」で字下げします。
 返信の引用は最小限にします。
 環境(OSとコンパイラ)や症状は具体的に詳しく書きます。
 返信の付いた投稿は削除しません。
 マルチポスト(多重投稿)はしません。

掲示板2

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧

No.26372

文字、文字列を16進に変換
投稿者---べた(2006/03/10 12:23:03)


文字、または、文字列を16進に変換しています。
例えば、「abc」→「616263」に変換しています。
一応、動くものなのですが、他に、良い方法とかありますか。

また、その逆を行いたいのですが、
「616263」→「abc」
としたいのですが、上手い方法を教えて下さい。

-- 文字、文字列を16進に変換---------
#include <limits.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

#define BYTE_CHARACTER ((CHAR_BIT + 3) / 4)

char *convertToHex (char * buffer, const void * chrstr, size_t size)
{
    const unsigned char *src = chrstr;
    unsigned char data;
    int j;
    size_t i;

    for (i = 0; i < size; ++i) {
        if (BYTE_CHARACTER == 2) {
            buffer[i * 2] = "0123456789ABCDEF"[src[i] / 0x10];
            buffer[i * 2 + 1] = "0123456789ABCDEF"[src[i] % 0x10];
        } else {

            data = src[i];
            for (j = BYTE_CHARACTER - 1; j >= 0; --j) {
                buffer[i * BYTE_CHARACTER + j] = "0123456789ABCDEF"[data % 0x10];
                data /= 0x10;
            }
        }
    }
    buffer[i * BYTE_CHARACTER] = 0;

    return buffer;
}

main()
{
    char buff[256];
    char str[256];

    memset(buff,'\0',sizeof buff);

    printf("Please input it. ? > ");
    if (gets(str) == NULL) {
        exit(-1);
    }

    convertToHex(buff,str,strlen(str));
    printf("CHAR : [%s]\n",str);
    printf("HEX  : [%s]\n",buff);
}


-- 16進のダンプ --------
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

unsigned char table_h[32] = {
    255,  10*16, 11*16, 12*16, 13*16, 14*16, 15*16, 255,
    255,  255,   255,   255,   255,   255,   255,   255,
    0,    1*16,  2*16,  3*16,  4*16,  5*16,  6*16,  7*16,
    8*16, 9*16,  255,   255,   255,   255,   255,   255
};

unsigned char table_l[32] = {
    255,  10,  11,  12,  13,  14,  15, 255,
    255, 255, 255, 255, 255, 255, 255, 255,
      0,   1,   2,   3,   4,   5,   6,   7,
      8,   9, 255, 255, 255, 255, 255, 255
};

main()
{
    char str[256];
    int i;

    i = table_h[getchar() & 0x1f];
    i += (int) table_l[getchar() & 0x1f];

    fprintf(stdout,"=========================================================\n");
    printf("DEC  : [%d]\n",i);
    printf("HEX  : [%x]\n",i);
    printf("CHAR : [%c]\n",i);
}




この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:文字、文字列を16進に変換 26373 Blue 2006/03/10 13:49:19
<子記事> Re:文字、文字列を16進に変換 26388 かずま 2006/03/11 15:35:56


No.26373

Re:文字、文字列を16進に変換
投稿者---Blue(2006/03/10 13:49:19)


sprintf,sscanfを使ってみました。


char* AnsiStrToHexCode( char* dest, const char* src )
{
    char* p = dest;

    while ( *src )
    {
        if ( sprintf( p, "%02X", ( unsigned char )( *src++ ) ) != 2 )
        {
            break;
        }
        p += 2;
    }

    return dest;
}

char* HexCodeToAnsiStr( char* dest, const char* src )
{
    char* p = dest;
    unsigned char c;

    while ( *src )
    {
        if ( sscanf( src, "%02x", &c ) != 1 )
        {
            break;
        }
        *p++ = c;
        src += 2;
    }
    *p = '\0';

    return dest;
}

int main( void )
{
    char s[ 256 ], h[ 256 ];

    scanf( "%s", s );
    AnsiStrToHexCode( h, s );
    printf( "HEX : %s\n", h );
    HexCodeToAnsiStr( s, h );
    printf( "STR : %s\n", s );

    return 0;
}



この投稿にコメントする

削除パスワード

No.26374

Re:文字、文字列を16進に変換
投稿者---Blue(2006/03/10 13:54:53)


追記+訂正

sprintfの戻り値判定はいらなかったカナ。
やるならば、break;する前に *p = '\0'; が欲しかったです。

文字バッファサイズは考えていません。


この投稿にコメントする

削除パスワード

No.26375

Re:文字、文字列を16進に変換
投稿者---べた(2006/03/10 17:00:03)


ありがとうございます。
試してみました。

コアダンプしました。
HexCodeToAnsiStr()関数で落ちているみたいです。
sscanf()が上手くいっていないみたいです。


この投稿にコメントする

削除パスワード

No.26376

Re:文字、文字列を16進に変換
投稿者---Blue(2006/03/10 17:27:22)


環境はどうなっていますか?
デバッグはできますか?
どんな文字列でだめでしたか?


この投稿にコメントする

削除パスワード

No.26377

Re:文字、文字列を16進に変換
投稿者---べた(2006/03/10 17:32:47)


>環境はどうなっていますか?
>デバッグはできますか?
>どんな文字列でだめでしたか?
環境は、Solaris8
コンパイルは、gcc
です。

gcc -o モジュール ソースファイル
で実行モジュールを作ってます。


「1」、「a」、「阿」
1バイト、2バイト文字でだめです。

文字、文字列から16進へは上手くいってますが、
16進から文字へ戻すでこけてます。



この投稿にコメントする

削除パスワード

No.26378

Re:文字、文字列を16進に変換
投稿者---Blue(2006/03/10 17:39:11)


sscanfの おそらく c の型がダメなんでしょう。
("x"はint型でした。)

unsigned char c;
int c;
・・・
*p++ = ( unsigned char )c;
とするとどうなりますか?


ソース中にprintf文を埋め込んである値を確認することも立派なデバッグ作業になります。


この投稿にコメントする

削除パスワード

No.26379

Re:文字、文字列を16進に変換
投稿者---べた(2006/03/10 18:16:23)


> unsigned char c;
> を
> int c;
>・・・
>*p++ = ( unsigned char )c;
上手く行きました。

こんなに簡単な方法でできるのですね。
深く考えすぎなのですか。

>ソース中にprintf文を埋め込んである値を確認することも立派なデバッグ作業になります。
printf文でデバックはしたのですが、printf文までいけませんでした。


この投稿にコメントする

削除パスワード

No.26388

Re:文字、文字列を16進に変換
投稿者---かずま(2006/03/11 15:35:56)


> 文字、または、文字列を16進に変換しています。
> 例えば、「abc」→「616263」に変換しています。
> 一応、動くものなのですが、他に、良い方法とかありますか。

BYTE_CHARACTER が 2 の場合だけですが、
#include <stdio.h>
#include <string.h>

char *convertToHex(char * buffer, const void * chrstr, size_t size)
{
    static char hex[] = "0123456789ABCDEF";
    const unsigned char *src;
    char *dst = buffer;

    for (src = chrstr; size--; src++) {
        *dst++ = hex[*src >> 4];
        *dst++ = hex[*src & 15];
    }
    *dst = 0;
    return buffer;
}

int main(void)
{
    char str[256], buff[512];

    printf("Please input it. ? > ");
    if (gets(str) == NULL) return 1;

    convertToHex(buff, str, strlen(str));
    printf("CHAR : [%s]\n", str);
    printf("HEX  : [%s]\n", buff);
    return 0;
}

> また、その逆を行いたいのですが、
> 「616263」→「abc」
> としたいのですが、上手い方法を教えて下さい。

文字コードが ASCII の場合ですが、
#include <stdio.h>
#include <ctype.h>

#define HEX(c)  ((c >> 6) * 9 + c & 15)

int main(void)
{
    int h, l;

    while (isxdigit(h = getchar()) && isxdigit(l = getchar()))
        putchar(HEX(h) << 4 | HEX(l));
    putchar('\n');
    return 0;
}



この投稿にコメントする

削除パスワード

No.26389

Re:文字、文字列を16進に変換
投稿者---べた(2006/03/11 20:41:20)


>> 文字、または、文字列を16進に変換しています。
>> 例えば、「abc」→「616263」に変換しています。
>> 一応、動くものなのですが、他に、良い方法とかありますか。
>
>BYTE_CHARACTER が 2 の場合だけですが、
BYTE_CHARACTER が 2 以外の場合はどうなりますか。
私が載せたものでもいいのでしょうか。



この投稿にコメントする

削除パスワード

No.26399

Re:文字、文字列を16進に変換
投稿者---かずま(2006/03/12 15:31:42)


> BYTE_CHARACTER が 2 以外の場合はどうなりますか。
> 私が載せたものでもいいのでしょうか。

それでかまいませんが、BYTE_CHARACTER はコンパイル時に決まる定数ですか
ら、if (BYTE_CHARACTER == 2) が実行時に変化することはなく、条件が不成立
のほうの処理が無効になります。最近のコンパイラは賢いので無駄なコードは
生成しないと思いますが、こういうのは前処理の #if で解決するほうがよいと
思います。参考となるプログラムを挙げておきます。
#include <stdio.h>
#include <string.h>

#define BYTE_CHARACTER  3

char *convertToHex(char * buffer, const void * chrstr, size_t size)
{
    static char hex[] = "0123456789ABCDEF";
    const unsigned char *src;
    char *dst = buffer;

    for (src = chrstr; size--; src++) {
#if BYTE_CHARACTER == 2
        *dst++ = hex[*src >> 4];
        *dst++ = hex[*src & 15];
#else
        int i, data = *src;
        for (i = BYTE_CHARACTER; --i >= 0; data >>= 4)
            dst[i] = hex[data & 15];
        dst += BYTE_CHARACTER;
#endif
    }
    *dst = 0;
    return buffer;
}

int main(void)
{
    char str[256], buff[512];

    printf("Please input it. ? > ");
    if (gets(str) == NULL) return 1;

    convertToHex(buff, str, strlen(str));
    printf("CHAR : [%s]\n", str);
    printf("HEX  : [%s]\n", buff);
    return 0;
}



この投稿にコメントする

削除パスワード

No.26413

Re:文字、文字列を16進に変換
投稿者---べた(2006/03/13 16:35:18)


ありがとうございます。

勉強になります。


この投稿にコメントする

削除パスワード

No.26414

Re:文字、文字列を16進に変換
投稿者---べた(2006/03/13 17:05:03)


ありがとうございます。

「BYTE_CHARACTER 3」とデファインされているので
#ifのルートではなく、#elseのルートに入ります。

処理中に、定数がかわることは、ありえないです。
BYTE_CHARACTERで指定する値によっても、表示の内容
ことなってきます。


BYTE_CHARACTER 3 の場合
 1 : 031
BYTE_CHARACTER 4 の場合
 1 : 0031

となりますから、
2バイトで表示させたいので、正しくしたいとおもいます。



この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧