プロが教えるわが家の防犯対策術!

最大10桁の16進数文字を数字の10進数で表示するコードを記述する事は出来たのですが、その逆が、どうしてもうまくいきません。16進数文字を数字の10進数で表示させるコードをベースに何処の箇所を修正すれば10進数文字を16進数に変換出来るのでしょうか?初心者で難しいコードが解らない為、ダラダラとしたコードで申し訳ございません。
また、今、C言語の文字列の勉強をしてる為、いくつか仕様がありますので、宜しくお願いします。
(1)入力された10進数文字を数値の10進数に変換させた後に、16進数の文字として表示させる。
(2)「printf」以外の関数は使用しない。
(3)最後に表示させる時は「%s」を使用する。
-------------------------------------------------
【最大10桁の16進数文字を数字の10進数で表示】
#include "stdafx.h"
#define MEX 10
/*「function」:入力文字された文字数*/
char ToInt( char cInt)
{
int mal=0;
switch (cInt){
case '0':mal=0;break;
case '1':mal=1;break;
case '2':mal=2;break;
case '3':mal=3;break;
case '4':mal=4;break;
case '5':mal=5;break;
case '6':mal=6;break;
case '7':mal=7;break;
case '8':mal=8;break;
case '9':mal=9;break;
case 'a':mal=10;break;
case 'A':mal=10;break;
case 'b':mal=11;break;
case 'B':mal=11;break;
case 'c':mal=12;break;
case 'C':mal=12;break;
case 'd':mal=13;break;
case 'D':mal=13;break;
case 'e':mal=14;break;
case 'E':mal=14;break;
case 'f':mal=15;break;
case 'F':mal=15;break;
}
return (mal);
}

/*「function」:位の計算*/
double HexAcc( double n )
{
int i;
double ans=1;
for( i=0; i<n; i++ ){
ans *= 16;
}
return (ans);
}

int _tmain(int argc, _TCHAR* argv[])
{
int i=0,n=0,j=0,k=0,s=0,m=0;
char decimal[ 255 ], ditto[ 255 ],sub[ 255 ];

/*入力されない場合*/
if( argc > 1 ){
decimal[s] = argv[1][i];
}
else{
printf("16進数を入力してください。\n");
return 1;
}
/*subに文字として'\0'を代入*/
for( k=0; k<=128; k++ ){
sub[k] = '0';
}

/*入力された文字数を受取る*/
for( i=0; argv[1][i] != '\0'; i++ ){
decimal[i] = argv[1][i];
}
decimal[i] = '\0';

/*空白文字のチェック*/
for( i=0; decimal[i] != '\0'; i++ ){
if( decimal[i] != ' ' ){
ditto[n] = decimal[i];
n++;
}
}
/*'\0'を代入(文字列の終端)*/
ditto[n]='\0';
/*「0」から「9」のループ*/
for( n=0; ditto[n] != '\0'; n++ ){
if(( ditto[n] == '0' ) || ( ditto[n] == '1' ) || ( ditto[n] == '2' ) || ( ditto[n] == '3' )
|| ( ditto[n] == '4' ) || ( ditto[n] == '5' ) || ( ditto[n] == '6' ) || ( ditto[n] == '7' )
|| ( ditto[n] == '8' ) || ( ditto[n] == '9' ) || ( ditto[n] == 'A' ) || ( ditto[n] == 'B' )
|| ( ditto[n] == 'C' ) || ( ditto[n] == 'D' ) || ( ditto[n] == 'E' ) || ( ditto[n] == 'F' )
|| ( ditto[n] == 'a' ) || ( ditto[n] == 'b' ) || ( ditto[n] == 'c' ) || ( ditto[n] == 'd' )
|| ( ditto[n] == 'e' ) || ( ditto[n] == 'f' )){
}else{
printf("エラー\n 16進数以外の文字が含まれております。\n");
return 0;
}
}
/*桁数のループ*/
for( n=0; ditto[n] != '\0'; n++ ){
m = m + 1 ;
}
/*桁数の判断*/
if( m <= MEX ){
}else{
printf("エラー\n入力文字数は、%d文字以内にしてください。\n",MEX);
return 0;
}
/*subにdittoを代入*/
for( n=0; ditto[n] != '\0'; n++){
sub[MEX-m+n] = ditto[n];
}
/*'\0'を代入(文字列の終端)*/
sub[MEX] = '\0';*/
/*「double型:addの初期化」「int型:ans初期化」add・ansの初期化*/
double ans=0;
double add=0;
/*sub[0]からsub[9]の計算*/
for( n=0; sub[n] != '\0'; n++){
ans = ToInt(sub[n]);
add += ans * HexAcc(MEX-n-1);
}
/*最大10桁の16進数文字を数字の10進数で表示*/
printf("最大10桁の16進数文字を数字の10進数に変換した値は %f \n",add);

A 回答 (4件)

ているようですね。


・今回は10進文字列→数値→16進文字列に変換したいのですか。
 文字列のお勉強をしているようですが、C言語で数値をどう表現しているかも一緒に
 お勉強して下さい。毎回『数値の10進数』と表現していますが最初読んだとき意味が
 分かりませんでした。文字列を10進数で解釈して数値に変換するなら分かりましたけど。
・C言語の char、short、int、long、long long 型(unsignedも含む)などはすべて内部では
 2進数で表現(管理)しています。なので数値に変換した時点で『数値の10進数』とか
 『数値の16進数』とか『数値の2進数』という区別はなくなります。全部2進表現ですので。
 (もし表現するならば『文字列を10進数で解釈した数値』という方がしっくりします)
>(1)入力された10進数文字を数値の10進数に変換させた後に、16進数の文字として表示させる。
 ↑
 入力された10進文字列を数値(double型)に変換させた後に16進文字列に変換して表示で良いかな。解釈。
 大きく分けて2つの方法があります。
・1つ目(小さい位の桁から変換)
 (1)double 型の ans を 16 で割ったあまりを求める。
 (2)求めたあまりを '0'~'9'、'A'~'F'の文字に変換。
 (3)double 型の ans を 16 で割って ans に代入する。
 (4)double 型の ans が 0 以上なら(1)へ戻り繰り返し、0 ならループを抜ける。
 (5)小さい位の桁から変換しているので表示する際は逆に大きいくらいから表示すること。
・2つ目(大きい位の桁から変換)
 (1)最初に double 型の ans が 16 進数で何桁分あるか計測。
 (2)仮に8桁であった場合は16^7乗(=268435456)から順に16^6乗、16^5乗、…16^0乗と割っていく。
 (3)(2)で割った数値を tmp とすると、この tmp を 16 で割ったあまりを求める。
 (4)求めたあまりを '0'~'9'、'A'~'F'の文字に変換。
 (5)大きい位の桁(8とか)から小さい位の桁(1)まで順に処理して終了。
 この2つの方法で実現できます。1つ目は変換と表示順が異なるので注意。
>(2)「printf」以外の関数は使用しない。
 ↑
 これは変換関数を自作せよという事でしょう。
 上記の方法を関数名 ValueToHexStr() という感じで用意すれば良いでしょう。名前は自由ですが。
 プロトタイプは
 void ValueToHexStr( char buff[], double value );
 という感じでしょうかね。
>(3)最後に表示させる時は「%s」を使用する。
 ↑
 char buff[ 32 ];
 double ans = 11259375.0; ←16進数で『0xABCDEF』が入っている。
 
 ValueToHexStr( buff, ans );
 printf( "10進数を16進文字列に変換した文字列は %s\n", buff );
 こんな感じの処理を質問にあるソースの最後に追加すれば良いだけです。
・以上。出来たら捕捉に貼り付けてみて下さい。

この回答への補足

Oh-Orangeさま
mai-07_mai12と申します。
毎回、ご親切なアドバイスありがとうございます。
アドバイスを参考に、コードを作成してみました。当初は10桁で作成を行おうとしたのですが最終的に5桁になってしまいました。
どうしても、改善したい点があります。コード上の「商と余りを配列に代入」の箇所をfor文で作成したのですが、うまくいかず1文1文のコードになってしまいました。難しいコードですと理解出来ない場合がありますので「商と余りを配列に代入」する箇所の所だけ、for文で作成するコードを教えていただけないでしょうか?

補足日時:2008/02/05 22:31
    • good
    • 0
この回答へのお礼

補足欄にコードを書き込めなかったので、新規に質問ページに作成したコードを掲載しました。
http://oshiete1.goo.ne.jp/qa3748427.html

お礼日時:2008/02/05 23:09

★頑張っているようですね。


と1行目を記述したかった。
文字が欠けてたね。
    • good
    • 0

>(1)入力された10進数文字を数値の10進数に変換させた後に、16進数の文字として表示させる。


>(2)「printf」以外の関数は使用しない。
>(3)最後に表示させる時は「%s」を使用する。

32bit限定。不足なら増やしてください。

char *s = "305441741";//10進文字列・・・例
char h[ 9 ];//16進文字列の格納領域
unsigned int n = 0;//10進数値の変数
int i;
//printf( "%s\n", s );//10進文字列表示・・・以下デバッグ用
while( *s ) {
n *= 10;
n += *s - '0';
s++;
}
//printf( "%d\n", n );//10進数値表示
//printf( "%x\n", n );//16進数値表示
s = h;
for( i = 0; i < 8; i++ ) {
*s++ = "0123456789ABCDEF"[ n / 0x10000000 ];
n <<= 4;
}
*s = '\0';
printf( "%s\n", h );//16進文字列表示・・・これは答え
    • good
    • 0

まず、手で計算するときにはどうするかを考えてみます。


例えば、十進数の1234567890(十二億三千四百五十六万七千八百九十)を
十六進数に変換する場合、繰り返し16で割り、商と余りを保存します。
こんな風になります。

16)1234567890
16)77160493  … 2
16)4822530   … 13
16)301408   … 2
16)18838    … 0
16)1177    … 6
16)73     … 9
16)4      … 9

これ以上割れなくなりました。この状態で、
最後の商(4)から始めて、余りを下(最後)から上(最初)に
向かって順にたどります。途中の13はDとなります。

結果として、十進数の1234567890を十六進数に変換すると、499602D2となります。
このロジックをプログラミングしてください。

ただし、10桁の十進数はunsigned long型でも格納しきれない場合があります。この場合は別の考え方が必要です。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!