- 締切済み
8桁の2進数を10進数に変換する方法を教えてください。
キーボードから2進数を入力した値を10進数に変換し、変換結果を出力する方法が解りません。作成するにあたり仕様があり、私一人では解決できないので相談させていただきました。 <仕様は以下の通りです> (1)このプログラム(8桁の2進数を10進数に変換)をする際は、最後に出力する時(printf)以外は関数を使ってはいけません。 (2)キーボードから2進数を入力させる。 (3)空白(ブランク)が入力されても変換可能にする。 (4)入力された2進数は8桁にし、8桁以上の場合はエラーを出す。 (5)2進数の「0」と「1」以外の文字が入力された場合はエラーを出す。 (6)バイナリ変換をし、変換結果を出力する。 以上になります。 まだ、C言語を勉強を習い始めの初心者です。どうか、ご回答のほど宜しくお願いします。
- みんなの回答 (7)
- 専門家の回答
みんなの回答
(1週間遅れで「質問」が来た・・なぜ?) ★0 1 0は、010とします。【A】 ★8桁未満の2進数を「8桁に」するには、末尾に0を埋める方法【B】と、冒頭に0を埋める方法【C】の2とおりあり、双方求めます。 010 → 01000000 10進で64 【B】 010 → 00000010 10進で 2 【C】 ◆表示用に整形した文字列を作成しています【D】。 #include <stdio.h> #include <stdlib.h> #include <string.h> void Error_Stop( int iSw ) { if( iSw ) printf( "エラー発生 CODE %d\n", iSw ); exit( 0 ); } void main() { char cBinStr[64], cWork[16], cStrB[16], cStrC[16]; int i, nn, iErr, iValB, iValC; while( 1 ){ printf( "2進数を8桁以内で( /:終了)\n" ); nn = 0; gets( cBinStr ); strcpy( cStrB, "00000000" ); strcpy( cStrC, "00000000" ); for( i = 0; i < 64; i++ ){ if( 0x00 == cBinStr[i] ) break; // 終端 if( 0x20 == cBinStr[i] ) continue; // 【A】 if( 0x2F == cBinStr[i] ) Error_Stop( 0 ); // /(0x2F):終了 iErr = 0; if( '0' != cBinStr[i] ) iErr++; if( '1' != cBinStr[i] ) iErr++; if( 2 == iErr ) Error_Stop( 5 ); // エラー(5) cWork[nn++] = cBinStr[i]; if( 8 < nn ) Error_Stop( 4 ); // エラー(4) } for( i = 0; i < 8; i++ ){ // 8桁文字列作成【D】 if( i < nn ) cStrB[i] |= cWork[i]; //【B】 if( i > ( 7 - nn ) ) cStrC[i] |= cWork[nn+i-8]; //【C】 } iValB = 0; iValC = 0; for( i = 0; i < 8; i++ ){ iValB += (int)( 0x01 & cStrB[i] ) << ( 7 - i ); // 【B】 iValC += (int)( 0x01 & cStrC[i] ) << ( 7 - i ); // 【C】 } printf( "%s %3d\n", cStrB, iValB ); printf( "%s %3d\n", cStrC, iValC ); } } 注:インデントで全角空白を用いています(全角空白→タブコード)。
- jacta
- ベストアンサー率26% (845/3158)
やはり入力が一番難しいですね。 キーボードではなく標準入力でよいのであれば、C++なら (「C言語を勉強を習い始めの初心者です。」とはありますが、「C言語で作れ」とは書かれていないので) #include <iostream> #include <bitset> #include <stdio.h> int main() { std::bitset<9> binary; std::cin >> binary; if (!std::cin) { printf("エラー\n"); } else { if (binary[8]) { printf("エラー\n"); } else { printf("%lu\n", binary.to_ulong()); } } return 0; } とできるのかも知れません。 >>や!や[]は演算子だから関数を使ったわけではないというのは、ちょっと無理があるかもしれませんが...。 それに、前に0を多数入力して8桁を超えた場合にエラーにならないのも、不適合扱いされるかもしれません。
- luckymako
- ベストアンサー率55% (29/52)
これでどうでしょ? #include<stdio.h> #define BITS 8 int main(){ char *bin; int dec = 0; int error = 0; int i = 0; printf("Bin : "); gets(bin); while(error == 0){ switch(bin[i]){ case ' ': case '0': dec <<= 1; break; case '1': dec <<= 1; dec += 1; break; case '\0': error |= 1; break; default: error |= 2; break; } if(i > BITS) error |= 4; i++; } if(error == 1) printf("Dec : %d\n", dec); if(error & 2) printf("Err : Input is wrong.\n"); if(error & 4) printf("Err : Input is too long.\n"); }
- tig33
- ベストアンサー率50% (6/12)
ちょっと、誤字やら間違い(printf文の%dなど)がありました。再掲します。 > (1)このプログラム(8桁の2進数を10進数に変換)をする際は、最後に出力する時(printf)以外は関数を使ってはいけません。 この仕様(1)を正確に遵守すると、ANo.2のJactさんが回答されている通りなのですが、 > (2)キーボードから2進数を入力させる。 仕様(2)でキーボード入力を要求しているのですから、文字列入力関数くらいは、使用して良いものと解釈します。 問題の意図は、Cに用意されている標準関数(数学関数や文字列処理関数など)を使用しないで、自力で作りなさいと言うことだと思います。 > (3)空白(ブランク)が入力されても変換可能にする。 仕様(3)の意味は、ちょっと意味を理解しかねますが、キーボードから入力するのに、8桁に満たない場合を想定しているのか、0の代わりに空白を入力も可としているのかが明確ではありません。 > (4)入力された2進数は8桁にし、8桁以上の場合はエラーを出す。 仕様(4)では、8桁をオーバー(問題の8桁以上は間違い。8桁以上は8桁を含みます。)した場合を規定していますが、8桁未満を左詰の入力なのか右詰の入力なのかを規定していません。 以上の要件を補填して、以下の定義(規定)の下に、プログラムを作成すると、 (1) キーボード入力は、gets()関数を使用する。 (2) キーボード入力は、128文字以上の入力は、プログラムの動作を保証しない。 (3) 数字0の代わりに、空白の入力も可とする。 (4) 8桁未満の入力は、左詰、右詰両方の処理結果を表示する。 #define BIN_DIGIT (8) #define BUFMAX (128) char inbuf[BUFMAX]; /* キーボード入力文字列を入れる領域 */ int main(void) { int textlen, ct, DecVal_L, DecVal_H, wk_L, wk_R; /* 2進数の文字列をキーボードから入力する */ gets(inbuf); /* 入力した文字列の検証 */ textlen = 0; for(ct=0; ct<BUFMAX; ct++) { if( (inbuf[ct] == '0') || (inbuf[ct] == '1') || (inbuf[ct] == ' ') ) { textlen++; /* 後の処理(10進数に変換)のため空白を0に書き替えておく */ if( inbuf[ct] == ' ' ) { inbuf[ct] = '0'; } } else { if( inbuf[ct] != '\0' ) { printf("入力に0,1以外の文字が入力されました。\n"); return(1); } break; } } /* 入力文字列数が規定を超えたか? */ if( textlen > BIN_DIGIT ) { printf("入力が%d桁を超えています。\n", BIN_DIGIT); return(1); } /* 右詰の DecVal_R = 0; for(ct=0; ct<BIN_DIGIT; ct++) { if( inbuf[ct] == '\0' ) break; DecVal_R <<= 1; if( inbuf[ct] == '1' ) { DecVal_R |= 1; } } /* 左詰の処理 (注:if文は無くて良い。0ビットのシフトは変化無いから)*/ DEcVal_L = DecVal_R; if( textlen < BIN_DIGIT ) { DecVal <<= BIN_DIGIT - textLen; } /* 結果の表示 */ printf( "2進数(%s)を10進数に変換すると、左詰(%d)、右詰(%d)になります。\n", inbuf, DevVal_L, DecVal_R ); return(0); } こんな具合ですね。
- tig33
- ベストアンサー率50% (6/12)
> (1)このプログラム(8桁の2進数を10進数に変換)をする際は、最後に出力する時(printf)以外は関数を使ってはいけません。 この仕様(1)を正確に遵守すると、ANo.2のJactさんが回答されている通りなのですが、 > (2)キーボードから2進数を入力させる。 仕様(2)でキーボード入力を要求しているのですから、文字列入力関数くらいは、使用して良いものと解釈します。 問題の意図は、Cに用意されている標準関数(数学関数や文字列処理関数など)を使用しないで、自力で作りなさいと言うことだと思います。 > (3)空白(ブランク)が入力されても変換可能にする。 仕様(3)の意味は、ちょっと意味を理解しかねますが、キーボードから入力するのに、8桁に満たない場合を想定しているのか、0の代わりに空白を入力も可としているのかが明確ではありません。 > (4)入力された2進数は8桁にし、8桁以上の場合はエラーを出す。 費用(4)では、8桁をオーバー(問題の8桁以上は間違い。8桁以上は8桁を含みます。)した場合を規定していますが、8桁未満を左詰の入力なのか右詰の入力なのかを規定していません。 以上の要件を補填して、以下の定義(規定)の下に、プログラムを作成すると、 (1) キーボード入力は、gets()関数を使用する。 (2) キーボード入力は、128文字以上のの入力は、プログラムの動作を保証しない。 (3) 数字0の代わりに、空白の入力も可とする。 (4) 8桁未満の入力は、左詰、右詰両方の処理結果を表示する。 #define BIN_DIGIT (8) #define BUFMAX (128) char inbuf[BUFMAX]; /* キーボード入力文字列を入れる領域 */ int main(void) { int textlen, ct, DecVal_L, DecVal_H, wk_L, wk_R; /* 2進数の文字列をキーボードから入力する */ gets(inbuf); /* 入力した文字列の検証 */ textlen = 0; for(ct=0; ct<128; ct++) { if( (inbuf[ct] == '0') || (inbuf[ct] == '1') || (inbuf[ct] == ' ') ) { textlen++; /* 後の処理(10進数に変換)のため空白を0に書き替えておく */ if( inbuf[ct] == ' ' ) { inbuf[ct] = '0'; } } else { if( inbuf[ct] != '\0' ) { printf("入力に0,1以外の文字が入力されました。\n"); return(1); } break; } } /* 入力文字列数が規定を超えたか? */ if( textlen > BIN_DIGIT ) { printf("入力が%d桁を超えています。\n", BIN_DIGIT); return(1); } DecVal_R = 0; for(ct=0; ct<BIN_DIGIT; ct++) { if( inbuf[ct] == '\0' ) break; DecVal_R <<= 1; if( inbuf[ct] == '1' ) { DecVal_R |= 1; } } /* 左詰の処理 (注:if文は無くて良い。0ビットのシフトは変化無いから)*/ DEcVal_L = DecVal_R; if( textlen != BIN_DIGIT ) { DecVal <<= BIN_DIGIT - textLen; } /* 結果の表示 */ printf( "2進数(%s)を10進数に変換すると、左詰()、右詰()になります。\n", inbuf, DevVal_L, DecVal_R ); return(0); } こんな具合ですね。
- jacta
- ベストアンサー率26% (845/3158)
printf以外の関数が使えないのであれば、キーボードからの入力はI/Oを直接制御するしかありません。当然それにはハードウェアの仕様がわかる必要がありますし、環境によってはI/O制御が制限されるので実現できないこともあります。 なお、main関数が受け取る引数は、キーボードから入力されたものとは限らないので、仕様を満たすことができません。
- yaemon_2006
- ベストアンサー率22% (50/220)
#include <stdio.h> int main(int argc, char *argv[]) { char *p; int n, i, j; if(argc == 1){ printf("引数がない\n"); return 1; } for(i = 1, n = j = 0; i < argc; i ++){ p = argv[i]; while(*p){ if(j == 8){ printf("桁が多い\n"); return 1; } if(*p != '0' && *p != '1'){ printf("'%c'は使えない\n", *p); return 1; } n = n * 2 + (*p == '1'); p ++; j ++; } } printf("答え %d\n", n); return 0; }