16進数を入力しその2進数表現で0の最大連続数と連続開始ビット及び1の最大連続数と連続開始ビットを表示するプログラムを作成せよ。(最小桁を0ビットとする)
例.01110000011111111000000111110001の場合
0の最大連続数は9ビット目から始まる6ビット、1の最大連続数は15ビット目から始まる8ビットと表示されるようにする
という問題が出ました。16進数から2進数に変換することはできたのですが、そこからが何をしていいかわかりません。
お願いします。
#include<stdio.h>
int main(void){
int i;
unsigned int x;
printf("x = ");
scanf("%u",&x);
printf("%uの2進数表示 = \n",x);
for(i=32; i--;){
printf("%d",(x>>i)%2);
}
return 0;
}
教えてください!!
Re:教えてください!!
> scanf("%u",&x);
「16進数を入力する」という仕様に合致していません。
今は、符号なし10進数を入力するようになっています。
16進数の入力に対応するには、書式文字列を"%x"にする
必要があるはずです。
もっと厳密にするには、fgets関数あたりでいったん
文字列として受け取り、sscanf関数で有効な16進数かどうかを
判断する必要があります。
ところで、今回は最大何桁の16進数に対応する必要がありますか?
「16進数を入力する」という仕様に合致していません。
今は、符号なし10進数を入力するようになっています。
16進数の入力に対応するには、書式文字列を"%x"にする
必要があるはずです。
もっと厳密にするには、fgets関数あたりでいったん
文字列として受け取り、sscanf関数で有効な16進数かどうかを
判断する必要があります。
ところで、今回は最大何桁の16進数に対応する必要がありますか?
Re:教えてください!!
この問題では、数値であることを意識しなくてよさそうです。
文字列の世界だけで解けると思います。
今回はunsigned long型の範囲で考えるので、最大8文字(文字列終端の'\0'を除く)の
16進数に対応すればよいことになります。
入力した16進数の各々の桁について
0→0000
1→0001
2→0010
... (中略)
E→1110
F→1111
の変換を行ないます。
すると、0と1だけからなる最大32文字(文字列終端の'\0'を除く)の文字列ができます。
この文字列をいちばん右の第0ビットから調べていくロジックを考えるのが肝ですね。
文字列の世界だけで解けると思います。
今回はunsigned long型の範囲で考えるので、最大8文字(文字列終端の'\0'を除く)の
16進数に対応すればよいことになります。
入力した16進数の各々の桁について
0→0000
1→0001
2→0010
... (中略)
E→1110
F→1111
の変換を行ないます。
すると、0と1だけからなる最大32文字(文字列終端の'\0'を除く)の文字列ができます。
この文字列をいちばん右の第0ビットから調べていくロジックを考えるのが肝ですね。
Re:教えてください!!
ありがとうございます。文字列として考えればいいということは理解することができました。
>この文字列をいちばん右の第0ビットから調べていくロジックを考えるのが肝ですね。
右の0ビット順目から順番に調べていくにはどうしたらよいのでしょうか?
初心者なもので何回もすいません。
>この文字列をいちばん右の第0ビットから調べていくロジックを考えるのが肝ですね。
右の0ビット順目から順番に調べていくにはどうしたらよいのでしょうか?
初心者なもので何回もすいません。
Re:教えてください!!
一旦数値で受けて、右シフトしながら文字列に変換するほうが簡単じゃないですか。
並びも逆転するので、文字列として左から"strtok"と"strlen"で処理していけばいいし。
Re:教えてください!!
最大連続ビットが複数ある場合は、最下位のみ表示。
#include <stdio.h> #include <string.h> int Input(char *bin) { char buff[16]; int n, i; fgets(buff, 16, stdin); if(sscanf(buff, "%x", &n) != 1) return 0; for(i = 0; i < 32; i ++){ bin = '0' + (n >> i & 1); } bin = '\0'; return 1; } void Search(char *bin, int *max, int *maxp, char *token) { char bintemp[33]; char *work; int len; memcpy(bintemp, bin, 33); *max = *maxp = len = 0; work = strtok(bintemp, token); if(work == NULL){ *max = *maxp = 0; return; } if((len = strlen(work)) > *max){ *max = len; *maxp = work - bintemp; } while((work = strtok(NULL, token)) != NULL){ if((len = strlen(work)) > *max){ *max = len; *maxp = work - bintemp; } } return; } void Print(char *bin, int n) { if(!n) return; Print(bin + 1, n - 1); putchar(*bin); if(!(n % 4)) putchar(' '); if(n == 32) putchar('\n'); return; } void Mark(int maxp0, int maxp1) { int i; maxp0 = ((31 - maxp0) / 4) * 5 + (31 - maxp0) % 4; maxp1 = ((31 - maxp1) / 4) * 5 + (31 - maxp1) % 4; for(i = 0; i < 39; i ++){ if(i == maxp0 || i == maxp1) putchar('^'); else putchar(' '); } putchar('\n'); return; } int main(void) { int max0, maxp0, max1, maxp1; char bin[33]; if(!Input(bin)){ puts("Input Error"); return 1; } Search(bin, &max0, &maxp0, "1"); Search(bin, &max1, &maxp1, "0"); Print(bin, 32); Mark(maxp0, maxp1); printf("\'0\':%d~%d, \'1\':%d~%d\n", maxp0, max0, maxp1, max1); return 0; }