教えてください!!

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
たろう

教えてください!!

#1

投稿記事 by たろう » 13年前

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;
}

box

Re:教えてください!!

#2

投稿記事 by box » 13年前

> scanf("%u",&x);

「16進数を入力する」という仕様に合致していません。
今は、符号なし10進数を入力するようになっています。
16進数の入力に対応するには、書式文字列を"%x"にする
必要があるはずです。
もっと厳密にするには、fgets関数あたりでいったん
文字列として受け取り、sscanf関数で有効な16進数かどうかを
判断する必要があります。

ところで、今回は最大何桁の16進数に対応する必要がありますか?

たろう

Re:教えてください!!

#3

投稿記事 by たろう » 13年前

unsigned long型(32ビット)キー入力となっていました。

box

Re:教えてください!!

#4

投稿記事 by box » 13年前

この問題では、数値であることを意識しなくてよさそうです。
文字列の世界だけで解けると思います。

今回はunsigned long型の範囲で考えるので、最大8文字(文字列終端の'\0'を除く)の
16進数に対応すればよいことになります。
入力した16進数の各々の桁について
0→0000
1→0001
2→0010
... (中略)
E→1110
F→1111
の変換を行ないます。
すると、0と1だけからなる最大32文字(文字列終端の'\0'を除く)の文字列ができます。
この文字列をいちばん右の第0ビットから調べていくロジックを考えるのが肝ですね。

たろう

Re:教えてください!!

#5

投稿記事 by たろう » 13年前

ありがとうございます。文字列として考えればいいということは理解することができました。

>この文字列をいちばん右の第0ビットから調べていくロジックを考えるのが肝ですね。

右の0ビット順目から順番に調べていくにはどうしたらよいのでしょうか?
初心者なもので何回もすいません。

通りすがり

Re:教えてください!!

#6

投稿記事 by 通りすがり » 13年前

 
 一旦数値で受けて、右シフトしながら文字列に変換するほうが簡単じゃないですか。
並びも逆転するので、文字列として左から"strtok"と"strlen"で処理していけばいいし。
 

たろう

Re:教えてください!!

#7

投稿記事 by たろう » 13年前

右にシフトしていき0と1を判断しそれぞれ格納し最大連続数を探す方法、
最大連続数の開始ビットを表示する方法がわかりません。

通りすがり

Re:教えてください!!

#8

投稿記事 by 通りすがり » 13年前

 
 最大連続ビットが複数ある場合は、最下位のみ表示。
#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;
}

 

たろう

Re:教えてください!!

#9

投稿記事 by たろう » 13年前

ありがとうございます。
これから理解してみたいと思います。

閉鎖

“C言語何でも質問掲示板” へ戻る