![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?5a7ff87)
No.7ベストアンサー
- 回答日時:
#1です。
>ナル文字を使うと言うのが、あまり例題がなくわからなかったのですが、
Cの文字列操作の基本なので探せばいくらでもあると思います。プログラム中では'\0'でなく単に0と書かれているかもしれません。同じ値です。例えば、pがchar *だとして
for( ; *p; ++p) putchar(*p);
というのも0での文字列終端を調べてforループの終了条件としています。
>for文で、文字を検索しナル文字があれば、breakするループを作ればよいのでしょうか?
それでいいと思います。
>もう少しプログラムが上達する方法と、
ある程度のレベルに達すれば他人の良く出来たプログラムを読むのがいいと思いますが、まだその域ではないようですね。当面は入門書のマスターでしょうか。
>この問題の大きな流れがあれば回答おねがいします。
文字列入力して、先頭からループで1文字ずつ調べながら値を16倍して足しこんでいくということでいいでしょうが、0-9A-Fa-f以外の文字があったらどうするかも考えねばなりません。
今現在プログラミング言語C(バイブルと呼ばれているやつ)をしています。
一応、入門書を購入して、一通り読み終えてから、バイブルに挑戦しているのですが、この本は簡単な部類に入る本なのですか?
毎日頑張っていますが、なかなか進みません。
どうもありがとうございました。
No.9
- 回答日時:
>unsignedというものが分からなかったので調べてみたのですが、符号なしとありました。
>これは、符号があればどうなるのでしょうか?
符号有りでつくるのであれば、文字列の桁数を固定する必要があります。
例えば2文字の16進数にするのであれば、ABは負の数ですね。
負の数である事の判定は先頭ビットが立っているか否かです。
>また、for文内の
>for (i=0,j=strlen(x)-1,k=1 ;j>-1 ;j--,k*=16)
>最後のk*=16なのですが、私の中では始めて見る書き方なのです。
>for文内に書いてもよいのですか?
書いても良いんですよ。
k *= 16 ;
は
k = k*16 ;
と同じ意味です。
また16倍なので、
k = (k<<4);
k <<= 4 ;
というのも同じ事ですね。
i += (x[j]-'0')*k ;
という部分を使わせていただいて、コンパイルしたのですが、16進数1111を入れてみたところ、17という値しか返ってきませんでした。
なぜなんでしょうか?
引き続き色々頑張ってみます。
お時間がありましたら、何か回答をいただけたらと思います。ありがとうございました。
No.8
- 回答日時:
#5です。
よくご自分のソースを見てください。
i,jが混同していたり、hexstrも未定義です。
あなたのソースの修正箇所を下記に示しますので考えてみてください。
・int s[3]; → int s[4];
・for(j=0;j<=3;j++) → for(i=0; i<4; i++)
(i<=3 よりも i<4 とするのが普通です)
・for(n=0, i=0; i<strlen(hexstr); i++) {
→ for(n=0, i=0; i<4; i++) {
No.6
- 回答日時:
#1です。
>文字をキーボードから得るには、scanfを用いるのがよいのか、それともgetcharを用いるのがよいのかがわかりません。
普通は、fgets で1行入力します。
scanfは意図通り使うことが難しい関数なので初心者は使わないほうがいいでしょう。ちゃんとしたC入門書では「使ってはいけない関数」と説明してあるはずです。
>そして、関数に文字を渡すときは、配列にして渡すのが普通なのでしょうか?
16進2桁とか決まっているなら2個のintでもいいです。
int hex_to_bin(int x, int y) のような。
桁数が可変である場合は char [] で'\0'で終端した文字列形式を使うのが普通でしょう。
ナル文字を使うと言うのが、あまり例題がなくわからなかったのですが、
for文で、文字を検索しナル文字があれば、breakするループを作ればよいのでしょうか?
新しいことを知れば知るほど、この16進数の変換のプログラムの大きな流れがわからなくなってきます。
なにか、もう少しプログラムが上達する方法と、この問題の大きな流れがあれば回答おねがいします。
なんどもすいません。
No.5
- 回答日時:
>c-'0' と言う部分なんですが、
cは文字コードになっていることはわかりますよね。
'0'は、'0'の文字コード(ASCIIコードで0x30=48)です。
ASCIIコードでは、'0','1',...と並んでいるので'0'~'9'のコードなら
そのコード(c)から'0'のコードを引くと文字を数値に変換したことになりますよね。
・'0'-'0'=0
・'1'-'0'=1
...
・'9'-'0'=9
'A'~'F'の部分は自分で考えてください。(ほとんど同じですが)
'A'~'F'の部分は意味の理解し、自分なりのプログラムを作ってみたのですが、内容はara_araさんの内容と同じです。そこで、コンパイルしたところ
int main(void)
{
int i,j,n;
int s[3];
for(j=0;j<=3;j++)
s[i]=getchar();
for(n=0, i=0; i<strlen(hexstr); i++) {
n *= 16;
n += hex2bin(s[i]);
}
・・・
}
の、n += hex2bin(s[i]); の部分で、s[i]が、引数として渡せないとエラーが出ます。
この部分をどういう風に書き換えれば、エラーがでずにコンパイルすることが出来るでしょうか?
何度もすいません。
No.4
- 回答日時:
整数値としか無かったので取り急ぎunsigned intで書いてみました。
unsigned int xtou(char x[])
{
unsigned int i ;
int j,k ;
for (i=0,j=strlen(x)-1,k=1 ;j>-1 ;j--,k*=16){
if ( x[j] >= '0' && x[j] <= '9' ){
i += (x[j]-'0')*k ;
} else if ( x[j] >= 'a' && x[j] <= 'f' ){
i += (x[j]-'a'+10)*k ;
} else if ( x[j] >= 'A' && x[j] <= 'F' ){
i += (x[j]-'A'+10)*k ;
} else {
fprintf(stderr,"Error : xtou(\"%s\");\n",x);
exit(1);
}
}
return i ;
}
どうもありがとうございます。
unsignedというものが分からなかったので調べてみたのですが、符号なしとありました。
これは、符号があればどうなるのでしょうか?
また、for文内の
for (i=0,j=strlen(x)-1,k=1 ;j>-1 ;j--,k*=16)
最後のk*=16なのですが、私の中では始めて見る書き方なのです。
for文内に書いてもよいのですか?
もしよろしかったら、回答お願いします。
ありがとうございました。
No.3
- 回答日時:
こんな感じでどうでしょうか?
(0-9、A-F以外が含まれる場合は省略しています)
int hex2bin(char c)
{
if(('0'<=c) && (c<='9'))
return c-'0';
if(('A'<=c) && (c<='F'))
return c-'A'+10;
return -1;/* 0-9,A-F でない */
}
int main(void)
{
char hexstr[]="ABCD";
inti, n;
for(n=0, i=0; i<strlen(hexstr); i++) {
n *= 16;
n += hex2bin(hexstr[i]);
}
・・・
}
動かしていないので自信なしということにしておきます。
どうもありがとうございます。
ひとつ疑問におもったのが
c-'0'
と言う部分なんですが、以前にも何かの本でこのような部分があり、どういうことをしているのかが、わからなかったのですが、これはどういうことをしているのでしょうか?
よろしかったら、回答おねがいします。
No.2
- 回答日時:
ロジックを解析してみてください。
納得できれば、プログラムに起こすだけです。
関数開始
(文字列へのポインタを引数に渡す)
文字数だけループさせる
i番目の文字を判定
'0'の場合0
'1'の場合1
'2'の場合2
・・・
'F'の場合15
X=(X * 16)+上で判定した数値
ループ終了
Xを返す
関数終了
※Xは返り値を保存する変数
iはループ変数
文字を判定する場合、switch文を用いてcaseの分岐によってそれぞれに値を与える、と最初に考えついたのですが、みなさんの回答にあるように
c-'0'
といった式で繰り返し数値を与えるものが、もっとも効率のよいプログラムになるのでしょうか?
もっと斬新な、方法があれば教えてください。
よろしくおねがいします。
どうもありがとうございました。
No.1
- 回答日時:
>べき乗の関数を作ったとして、それぞれの値(こんかいはAとB)にそれぞれのべき乗した値をかけてやるには、どういった方法があるのでしょうか?
単に * で掛ければいいと思うのですが、どのあたりが問題と思っているのでしょうか?
16進数 ABCD を A*16^3+B*16^2+C*16^1+D というのが質問中に書かれた方法ですが、
((A*16+B)*16+C)*16+D というのがよくプログラムで使われる方法です。前者の方法に比べて
1) 16を掛けて足すという繰り返し処理でいい
2) 最初に全体の桁数を調べなくて良い
という利点があります。
なるほど!という一言に尽きる回答をありがとうございました。
いざ、関数の中身がわかったところで、ソースを書いていたんですが、文字をキーボードから得るには、scanfを用いるのがよいのか、それともgetcharを用いるのがよいのかがわかりません。
そして、関数に文字を渡すときは、配列にして渡すのが普通なのでしょうか?
なんどもすいません。よろしければ回答おねがいします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Excel(エクセル) エクセル 関数について質問です。 2 2022/10/03 11:14
- C言語・C++・C# このプログラミング誰か教えてくれませんか 3 2022/05/13 17:27
- その他(プログラミング・Web制作) プログラミング pythonの問題について 2 2022/04/19 00:41
- Excel(エクセル) Excel2019 列と列(2列)の数値の重複を調べたい 1 2023/05/11 13:35
- C言語・C++・C# このプログラミング誰か教えてくれませんか 2 2022/05/14 09:45
- C言語・C++・C# [C言語] コメント文字列を無視して、数値データを読み込むプログラム部分について 5 2022/10/05 11:03
- Java Java 南京錠 2 2023/02/04 11:46
- Excel(エクセル) エクセルでSUMIFS関数で条件範囲の部分が#valueになる。 4 2023/04/28 12:42
- Excel(エクセル) Excel 値を返す数式についてです 3 2022/11/21 20:08
- PostgreSQL 数値が定期的にあらわれる文字列から、いくつめに出現した数値が指定して切り出したい 1 2023/06/08 13:12
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
fgets関数を使用したときの文字...
-
fgetsで拾われる改行文字を削除...
-
CStringのFindで文字列検索を行...
-
fgetsでバッファ残留文字列を無...
-
単語数のカウントについて
-
反転した数値を表示させるやり方
-
sscanfとscanfの違いがよくわか...
-
全角文字のチェック
-
C言語で16進数文字列から16進数...
-
sscanfでフォーマットに合って...
-
ファイルを読み込みテキストフ...
-
c言語プログラミングHELP!
-
小文字のみを数える方法
-
itoaわかりません
-
c言語について array[i]-‘0’ こ...
-
C言語、単語ごとに改行したい
-
数字のINPUT
-
gets fgetsについて
-
”123456”といった整数を文字列...
-
Cで「大文字、小文字の判定」は...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
CStringのFindで文字列検索を行...
-
sscanfとscanfの違いがよくわか...
-
fgets関数を使用したときの文字...
-
反転した数値を表示させるやり方
-
Cで「大文字、小文字の判定」は...
-
charと%c , %s の関係について
-
C言語のステップ数をカウントす...
-
strstrを利用しない文字列検索...
-
C言語 空白の行(改行のみ)が...
-
fgetsで拾われる改行文字を削除...
-
文字列中に含まれる文字の個数...
-
C言語で16進数文字列から16進数...
-
itoaわかりません
-
文の意味
-
C言語 strlen 再入力を促す
-
fgetsでバッファ残留文字列を無...
-
全角文字のチェック
-
C++
-
ブランクのチェック
-
C言語、単語ごとに改行したい
おすすめ情報