掲示板利用宣言

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

 私は

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

掲示板2

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

No.29631

日本語を16進数へ 16進数を日本語へ
投稿者---mak(2007/01/29 12:24:05)


こんにちは

半角英数を16進数へ変換し16進数を半角英数に変換するプログラムはできているのですが
日本語を1文字読み込んで16進数へ変換し16進数から日本語へ変換するやり方がわかりません

こういう方法(関数とか)がありますよ、というのがあれば教えてください

WinXP Home SP2
Borland C++5.5.1

/***********半角英数Verのプログラム***********/
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<string.h>

void iword(void);
void icode(void);
void wfile(void);
void cfile(void);

int main(void)
{
    int q;

    puts("   before---after | input keyborad | reading file");
    puts("     word---code  |       IW       |      WF");
    puts("     code---word  |       IC       |      CF");
    printf("Please select in [IW IC WF CF]:");    /* IW = input word, IC = input code, WF = word file, CF = code file */
    q = getche();
    switch(q)   {
        case 'I':
        case 'i':
            q = getche();
            switch(q)   {
                case 'W':
                case 'w':
                    iword();
                    break;
                case 'C':
                case 'c':
                    icode();
                    break;
            }
            break;
        case 'W':
        case 'w':
            q = getche();
            switch(q)   {
                case 'F':
                case 'f':
                    wfile();
                    break;
            }
            break;
        case 'C':
        case 'c':
            q = getche();
            switch(q)   {
                case 'F':
                case 'f':
                    cfile();
                    break;
            }
            break;
    }

    return 0;
}

void iword(void)
{
    int a, i, len;
    char ss[80], fname[80];
    FILE *fw;

    printf("\nWord=");
    gets(ss);

    len = strlen(ss);

    printf("File name=");
    gets(fname);

    fw = fopen(fname,"a");
    for(i=0;i<=len-1;i++)   {
        a = ss[i];
        fprintf(fw, "%02X", a);
    }
    fputs("Z\n", fw);
    fclose(fw);

    return;
}

void icode(void)
{
    int a, i, len;
    char ss[80], code[2], fname[80];
    FILE *fw;

    printf("\nCode=");
    gets(ss);

    len = strlen(ss);
    
    printf("File name=");
    gets(fname);

    fw = fopen(fname,"a");
    for(i=0;i<=len-1;i+=2)  {
        if(ss[i] == 'Z')    {
            break;
        }
        sprintf(code, "%c%c", ss[i],ss[i+1]);
        a = strtol(code,NULL,16);
        fprintf(fw, "%c", a);
    }
    fputs("\n", fw);
    fclose(fw);

    return;
}

void wfile(void)
{
    int a;
    char fname[80];
    FILE *fr, *fw;

    printf("\nReading file name="); gets(fname);

    if((fr=fopen(fname,"r"))==NULL) {
        puts("Reading file is not found.");
        exit(1);
    }
    if((fw=fopen("Code.txt","w"))==NULL)    {
        puts("Writing file is not found.");
        exit(2);
    }

    while((a=fgetc(fr))!=EOF)   {
        fprintf(fw, "%02X", a);
    }
    fclose(fr);
    fclose(fw);

    return;
}

void cfile(void)
{
    int a;
    char fname[80], ss[3];
    FILE *fr, *fw;

    printf("\nReading file name="); gets(fname);

    if((fr=fopen(fname,"r"))==NULL) {
        puts("Reading file is not found.");
        exit(1);
    }
    if((fw=fopen("decode.txt","w"))==NULL)  {
        puts("Writing file is not found.");
        exit(2);
    }

    while(fgets(ss,3,fr)!=NULL) {
        if(ss[0] == 'Z')    {
            fputs("\n", fw);
            continue;
        }
        a = strtol(ss,NULL,16);
        fprintf(fw, "%c", a);
    }
    fclose(fr);
    fclose(fw);

    return;
}



全部半角英数なのは そのファイル自身を読み込んでテストするため です

よろしくおねがいします


この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:日本語を16進数へ 16進数を日本語へ 29634 sticky-bit 2007/01/29 13:31:37


No.29634

Re:日本語を16進数へ 16進数を日本語へ
投稿者---sticky-bit(2007/01/29 13:31:37)


>半角英数を16進数へ変換し16進数を半角英数に変換するプログラム

このプログラムに、試しに日本語のテキストを喰わせてみてはどうでしょう。




この投稿にコメントする

削除パスワード

No.29635

Re:日本語を16進数へ 16進数を日本語へ
投稿者---mak(2007/01/29 14:14:10)


キーボード入力で あいうえお と入力したら

FFFFFF82FFFFFFA0FFFFFF82FFFFFFA2FFFFFF82FFFFFFA4FFFFFF82FFFFFFA6FFFFFF82FFFFFFA8

となりました


この投稿にコメントする

削除パスワード

No.29636

Re:日本語を16進数へ 16進数を日本語へ
投稿者---sticky-bit(2007/01/29 14:57:16)


後は符号付き・符号なしの話だと思います。
がんばって修正してみてください。


この投稿にコメントする

削除パスワード

No.29637

Re:日本語を16進数へ 16進数を日本語へ
投稿者---YuO(2007/01/29 14:57:47)


>キーボード入力で あいうえお と入力したら
>FFFFFF82FFFFFFA0FFFFFF82FFFFFFA2FFFFFF82FFFFFFA4FFFFFF82FFFFFFA6FFFFFF82FFFFFFA8
>となりました

なるほど。charが符号付きな場合はそうなりますね。
fprintfの引数を,unsigned charにキャストしてやる必要があります。



この投稿にコメントする

削除パスワード

No.29638

Re:日本語を16進数へ 16進数を日本語へ
投稿者---mak(2007/01/29 15:39:36)


sticky-bitさん、YuOさん、ありがとうございます

iword()関数内を書き換えた結果

書き換え前
char ss[80], fname[80];
結果FFFFFF82FFFFFFA0FFFFFF82FFFFFFA2FFFFFF82FFFFFFA4FFFFFF82FFFFFFA6FFFFFF82FFFFFFA8

書き換え後
unsigned char ss[80];
char fname[80];
*unsinedをつけてもいいかわからなかったのでfname[80]をcharのままにしました
結果
82A082A282A482A682A8

このようになりました

次に
82A0を「あ」
82A2を「い」
このように変換するので (入力文字は5文字 16進数は20文字という事で 16進数4文字=日本語1文字と考えました)
 a = strtol("82A0",NULL,16);
 fprintf(fw, "%c", a);
かと思いましたが2バイト文字なので またつまってしまいました

一応実行させてみると表示がおかしくなってました (半角の■?)
%cを%sで実行すると当然のようにアプリケーションエラーがでました

この後 82A0 をどのようにすればいいでしょうか??


この投稿にコメントする

削除パスワード

No.29642

Re:日本語を16進数へ 16進数を日本語へ
投稿者---sticky-bit(2007/01/29 20:44:11)


>この後 82A0 をどのようにすればいいでしょうか??

0x82と0xA0をセットにすることを意識しすぎてはいませんか?

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

int main(void)
{
    char s[] = "82a082a282a4";      /* ファイルから読んだつもり */
    char *t, u[3];
    int n;
    
    for (t = s; *t; t += 2) {
        sprintf(u, "%c%c", t[0], t[1]);
        n = strtol(u, NULL, 16);
        putchar(n);      /* 実際には外部ファイルに書くつもり */
    }
    return 0;
}





この投稿にコメントする

削除パスワード

No.29643

Re:日本語を16進数へ 16進数を日本語へ
投稿者---mak(2007/01/29 21:31:22)


ありがとうございます

いくつか知らない部分(わからないor見たことの無い表記)があったので、その部分を勉強して
上記のソースを理解してからまた書き込みたいと思います

疑問に思った事
1、char *t; どうしてポインタを使うのか *char型のポインタ見た事無いです
2、for文にchar型が使えるのか *これも見た事無かったです
3、for文第2引数(?)の*tは何の意味なのか
4、sprintf()のt[0],t[1]は定数なのにどうして値が変わるのか
5、putchar()で82とA0を隣同士に表示させると日本語表記になるけど、どうして82とA0を別々に表示しないのか
 (82がきたら日本語って決まってるのかな?って思ってます)

とりあえずこれらを勉強して出直します


この投稿にコメントする

削除パスワード

No.29644

ごめんなさい
投稿者---mak(2007/01/29 21:44:52)


書き込みをした後にsticky-bitさんのプログラムを自分なりに書き換えたらいくつかの疑問が解決し、最初に載せたプログラムの書式(ポインタ不使用)でもできることがわかりました

>1、char *t; どうしてポインタを使うのか *char型のポインタ見た事無いです
strlen()で文字数を取得する必要が無いから

>2、for文にchar型が使えるのか *これも見た事無かったです
未解決

>3、for文第2引数(?)の*tは何の意味なのか
文字列終端と予想しました

>4、sprintf()のt[0],t[1]は定数なのにどうして値が変わるのか
未解決

>5、putchar()で82とA0を隣同士に表示させると日本語表記になるけど、どうして82とA0を別々に表示しないのか
> (82がきたら日本語って決まってるのかな?って思ってます)
未解決

残ってる疑問は・・・少々時間がかかりそうです;;

*連続投稿スイマセン><


この投稿にコメントする

削除パスワード

No.29647

Re:ごめんなさい
投稿者---sticky-bit(2007/01/30 09:55:29)


No.29642のコードを書き換えてみました。
意味合いは、29642と全く同じです。相互に置き換え可能です。

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

int main(void)
{
    char s[] = "82a082a282a4";      /* ファイルから読んだつもり */
    char *t, u[3];
    int n;
    
    t = s;
    while (*t != '\0') {
        sprintf(u, "%c%c", *t, *(t+1));
        n = strtol(u, NULL, 16);
        putchar(n);      /* 実際には外部ファイルに書くつもり */
        t += 2;
    }
    return 0;
}





この投稿にコメントする

削除パスワード

No.29649

Re:ごめんなさい
投稿者---sticky-bit(2007/01/30 10:14:23)


> (82がきたら日本語って決まってるのかな?って思ってます)

シフトJISコードにおいて、2バイト文字の第1バイトが0x82であるのは
2バイト文字全体のごく一部(数字、英字、ひらがな)です。



この投稿にコメントする

削除パスワード

No.29657

Re:ごめんなさい
投稿者---mak(2007/01/30 23:28:25)


書き換えまで行っていただいて本当にありがとうございます

>シフトJISコードにおいて、2バイト文字の第1バイトが0x82であるのは
>2バイト文字全体のごく一部(数字、英字、ひらがな)です。
では、第一バイトと第二バイトを別々に表示したらまた別の文字が表示される時もあるのでしょうか??
例えば
 ある文字の第二バイトと
 ある文字の第一バイトで
他の文字が表現されてしまったり

AABB CCDDと表示したいのに
AA BBCC DD と表示されたり

こういうことはありますか??

>sprintf(u, "%c%c", *t, *(t+1));
*tの番地とその次の番地内データをuに代入
>t += 2;
現在の番地から2つ次へ(現在が1なら3へ)移動

この解釈であっていますか??


この投稿にコメントする

削除パスワード

No.29659

Re:ごめんなさい
投稿者---sticky-bit(2007/01/31 09:38:23)


> AABB CCDDと表示したいのに
> AA BBCC DD と表示されたり
>
> こういうことはありますか??

実際にどうなるかは、例えばシフトJISコードにおける
2バイト文字の第1バイトと第2バイトに入りうるコードの範囲について
調べてみるとよいかもしれません。

> >t += 2;
> 現在の番地から2つ次へ(現在が1なら3へ)移動
>
> この解釈であっていますか??

今回の場合、tはsの先頭要素を指すことから始まって、
2要素ずつ指す先を変えていきます。
したがって、「2つ次へ移動」することは合っていますが、
「現在が1なら」という条件は正しくありません。
tがsの奇数番目の要素を指すことはないからです。



この投稿にコメントする

削除パスワード

No.29662

Re:ごめんなさい
投稿者---mak(2007/01/31 11:16:23)


ありがとうございます

今まで「ポインタって意味あんの〜?」ぐらいにしか認識してませんでした
文字列操作の時に使用すればfor文でstrlen()を使用しなくても済みますね
こりゃ便利と思いポインタを勉強する気になりました(今までなかったです。。。

ご丁寧に教えていただいて、ありがとうございました


この投稿にコメントする

削除パスワード

No.29663

Re:ごめんなさい
投稿者---sticky-bit(2007/01/31 13:06:32)


>文字列操作の時に使用すればfor文でstrlen()を使用しなくても済みますね

ポインタの使い道のごく一部に過ぎないです。
ポインタを理解しないままC言語を使うことはありえない、
と言っても過言ではないだろうと思います。


この投稿にコメントする

削除パスワード

No.29664

Re:ごめんなさい
投稿者---mak(2007/01/31 14:40:37)


>ポインタを理解しないままC言語を使うことはありえない、
>と言っても過言ではないだろうと思います。

 C言語にはポインタという重要な機能があります
 ポインタはC言語習得上の難関の一つ
ってどこかのサイトで見た事あります

これを機会にポインタの勉強してみようと思います


この投稿にコメントする

削除パスワード

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