• ベストアンサー

char型でビット列表示

char型の変数にビット配列を代入しそれを文字として出力させたいのです。 どこが間違っているのか分かりませんが一応流れを書いたプログラムを載せておきます。 char binary = 0; int i; for(i=0;i<8;i++){ if(省略) binary = binary & 11111110; else binary = binary | 00000001; binary = binary << 1; } printf("実行結果 %c",binary); 実行結果 00110110 というように最下位ビットに0か1を代入し、左シフトをし、というのを繰り返しprintf("%c",binary)でビット列を表示させたいのですが、これを実行すると結果は文字化けしたようなものが表示されます。 charの配列を作ってビット列を表示させるやり方はわかるのですが、学校の課題みたいなもので配列を使ってはいけないみたいなのです。 教科書を読んでも分からないので困っています。 よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • yama5140
  • ベストアンサー率54% (136/250)
回答No.5

No3 です。 今度は、「省略」の解明(◆)です。 「解明」してどうなるの、と問われればそれまてですが、何かの参考になればと。 ------------------------------------- むりくり、 >実行結果 00110110 になるように、プログラムしてみました。 ------------------------------------- #include <stdio.h> #define un_char unsigned char void main() { int i; un_char cBinary = 0x00, cWork; for( i = 0; i < 8; i++ ){ if( ( 0 == i ) || ( 1 == i ) || ( 2 == i ) || ( 5 == i ) ) cBinary &= (un_char)0xFE; // ◆ else cBinary |= 0x01; cBinary <<= 1; } for( i = 0; i < 8; i++ ){ // 1ビットずつの表示(2進風?) cWork = cBinary >> ( 7 - i ); cWork &= 0x01; cWork += 0x30; printf( "%c", cWork ); } } ★重要 1 と「表示」したいとき、%c フォーマット指定子をもちいて '1' (0x31)を出力 0 と「表示」したいとき、%c フォーマット指定子をもちいて '0' (0x30)を出力 ----------------------------------------- >これを実行すると結果は文字化けしたようなものが表示されます。 ★理解できたのではないでしょうか(前の回答のアスキーコード表と併せて)。

その他の回答 (4)

  • jk39
  • ベストアンサー率54% (366/670)
回答No.4

省略で何をしているかわかりませんが、 アドバイスをひとつ。 >for(i=0;i<8;i++){ > if(省略) binary = binary & 11111110; > else binary = binary | 00000001; > binary = binary << 1; >} for文の8周目(最終周)の左シフトが余計です。 計算結果が9bitになってしまいます。 (実際はcharが8bitなので、最初の1bitの情報が欠けてしまいます。)

  • yama5140
  • ベストアンサー率54% (136/250)
回答No.3

(「回答」ではありません) 「ビット配列」とか「左シフト」の文字を見ると、 「char型の変数に」は、「unsigned char型の変数に」とした方がよいかと・・。  (「趣味の世界」と言われればそのとおりですが) #include <stdio.h> void main() { unsigned char cAAA = 0x80; char cBBB = 0x80; cAAA >>= 1; cBBB >>= 1; printf( "%02X\n", cAAA ); printf( "%02X\n", cBBB ); } これを実行すると、 40 FFFFFFC0 (オーバーフロー) となります(「左シフト」だけならいいのですが)。 《参考》 http://e-words.jp/p/r-ascii.html http://www.k-cube.co.jp/wakaba/server/format.html

noname#63784
noname#63784
回答No.2

フォーマット指定子 %c について調べてみてください 00110110=0x36 を文字表示させたら'6'じゃないんですかね。へんな文字が表示されますか? ビット表示するには1回でまとめて printf("実行結果 %c",binary); ではできないと思います(%c以外でも) 1ビットずつ表示してください

  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.1

★アドバイス ・C言語では2進表記は出来ません。 >if(省略) binary = binary & 11111110;  ここの部分の『11111110』を『0xFE』にでもすれば良いでしょう。 >else binary = binary | 00000001;  ここも同じく間違い。 >charの配列を作ってビット列を表示させるやり方はわかるのですが、学校の課題みたいなもので配列を >使ってはいけないみたいなのです。  ↑  ビット演算のお勉強ですね。  『(省略)』部分が不明なのでこれ以上のアドバイスは出来ません。  とにかく2進数は使えません。16進数などで指定して下さい。

関連するQ&A

  • char型の二次元配列の意味が分からないのです・・・。

    char型の二次元配列の意味が分からないのです・・・。 char namae[5][10] = { "a1", "a2", "a3", "a4"  }; printf("%s\n",namae[1]); という文があったのですが、これは実行するとa2と表示されました。どうしてなのでしょう。 そもそもcharは文字1文字ですよね。char[5]という一次元配列に5文字の文字列を入れることができるというのは分かります。でもchar[5][10]ってどんな文字列を入れるのでしょうか。 どうして初期化で"a1"という二文字を順々と並べるのか、printfでどうしてnamae[1]なのかが意味不明です。二次元配列だからnamae[1][0]とかで指定するのではないのかと思うのですが。 とにかく混乱です(>_<) ご存知の方、教えていただけませんか?

  • 数値を2進数文字列に変換するものなんですが・・・

    数値を2進数の文字列に変換するプログラムを関数として作成しているんですが、わからないことがあるのでお願いします。 char *itob(int value, int size, char binary[]) { int count = 0; /* binaryの添え字 */ int bit = size * 8; /* ビットになおす */ int mask = 1 << bit - 1; /* 先頭ビットに1を立てる */ /* 数値を2進数の文字列に変換する処理 */ do { if(value & mask) { /* valueとmaskのAND(論理積) */ binary[count] = '1';/* '1'を代入 */ }else { binary[count] = '0';/* '0'を代入 */ } value <<= 1; /* valueを左へ1ビットシフト */ count++; /* countを1たす */ }while(count < bit); /* 繰り返しを行う条件 */ binary[count] = '\0'; /* 最後に'\0'を入れる */ return binary; /* 変換した値を戻り値として返す */ } この前にもプログラムがありますが、コンパイルして実行する際に 10001 1110 と入力したら、 11111 という答えを出したいのですが、 これを実行すると、 00000000000000000000000000011111 となってしまいます。 これを11111とするためにはプログラムにどのような処理をすればよいのかわかりませんのでどなたかおわかりのかた解説をお願いします。

  • 文字列の扱い方

    初歩的な質問ですみません… str文字列からcという文字を見つけたら添字を返すという関数を作ったのですが、 iにこの関数を代入して、if文の制御式にiを使って比較するまでは正常なのですが、 真文にiを使うと何故か偽文(という言い方でいいのでしょうか…この場合("そんな値はありません。"というところです)が実行されてしまいます。 よろしければご教授お願い致します。 #include <stdio.h> int str_char(const char str[],int c) { int len = strlen(str); int i; for (i = 0;i < len;i++) { if (str[i] == c) return i; } return -1; } int main() { char str[64] = "Fucking Brutal Death Metal"; int ch,i; printf("どの文字を調べますか?"); scanf("%c",&ch); i = str_char(str,ch); if (i >= 0) printf("その文字は%d番目にあります。",str_char(str,ch) + 1); //何故かiだと動かない else printf("そんな値はありません。"); return 0; }

  • char型のポインタ配列に変数の値の代入できる?

    c言語でchar型のポインタ配列に変数の値を代入できるのでしょうか? 例えば int A[10]={1,2,3,4,5,6,7,8,9,10}; char *C[10]; のCに配列Aの中のデータを文字列として入れたいのです。 C[0]="A[0]"としてもA[0]という文字列が代入されてしまうだけなので… よろしくお願いします。

  • 文字列の検索&排除をするプログラム

    「a=i;」とするとご存知の通り、aにiという変数を代入します。 しかし、変数としてではなく「文字(char型)」として処理したいと考えております。 例えば、「1,2,3,a,4,5,6」という文字列を1文字ずつ読み込み、 「a」という文字であれば表示しない、 という感じのプログラムを作成したいと思います。 つまり、「1,2,3,a,4,5,6」が「1,2,3,4,5,6」となります。 moji[]に「1,2,3,a,4,5,6」をchar型で代入したときの プログラムの例を書きます。 for (i = 0; i <= 6; i++){ if(moji[i]==a){//何もしない、ちなみに間違えています。 } else{//a以外が表示される printf("%c", moji[i]); } } 質問は「moji[i]==a」この部分を文字(char型)の「a」とし、 「1,2,3,a,4,5,6」を「1,2,3,4,5,6」の様に処理したいのですが、 どうしたらよろしいでしょうか?

  • 配列の渡し方と表示の仕方

    初心者です。 以下のメイン関数で実行をしたところ、 定義した文字列の最後の文字しか表示されません。 関数に上手く引数として配列が渡されていないか、 表示のさせ方が悪いと思うのですが、よく分かりません。 int main(void) { char str[CASENUM][10] = {'abcdef','abcde','abcd','abc'}; int startIndex[CASENUM] = {2,1,3,1}; char expected[CASENUM][10] = {'abcdef','abcde','abcd','abc'}; int i,m; char res; for(i = 0; i < CASENUM; i++) { printf("%c",str[m][i]); res = *subString(str[i],startIndex[i]); printf("実行結果:%c , 期待結果:%c\n", res, expected[i][10]); } return 0; } よろしくお願いします。

  • 空白を含んだ文字列がうまく格納(表示)できない

    こんにちわ。 空白(スペース)の入った文字列の格納(表示)について質問させてください。 以下のプログラムを実行すると、空白の含む文字列がうまく表示されません。 例えば、 in the worldと入力しても、inしか格納されていないみたいです。それはなぜでしょうか? また、どうすればそれを格納、表示させることができるのでしょうか?教えてください。よろしくお願いいたします。 #include <stdio.h> #include <string.h> main() { char buf[BUFSIZ]; char moji[31]; int i; printf("Input string: "); fgets(buf, sizeof(buf), stdin); moji[31] = '?0'; sscanf(buf, "%s", moji); i = 0; while (moji[i] != '?0') { printf("%c",moji[i]); i = i + 1; } printf("?n"); printf("%d letters?n", i); } 【実行例】 csx01:~> gcc prog.c csx01:~> a.out Input string: in the world in 2 letters

  • ソースコードの間違い (C言語)

    変数に、文字列を入れた配列の文字列の最後の要素数を入れたいのですが(つまり'\0')、うまくいきません。いつも2個多い値になってしまいます。 #include <stdio.h> void main() { char moji[100]={0}; int c=0; fgets(moji,sizeof moji,stdin); while( moji[c] != '\0' ) ++c; printf("\n%d\n",c); // } 例えば5文字の1ビット文字を入れると、最後の文字はmoji[4]にあるのでprintfで4と表示されるはずじゃないですか。でも6になるんです。いつも+2の値になるんですよ。どうやらfgetsを使っているからそうなるらしく、scanfを使うと結果は1多い値に、普通に配列に直接文字列を代入すると正常な結果になります。別にcに-2してもいいのですが、それはなんだか癪といいますか・・・。なぜこういうことがおきるのでしょうか?回答よろしくお願いします。

  • ビット列を走査するプログラムの関数化

    char型の変数に0or1を入れて擬似的にビット列にした配列をLSBからMSBまで走査し、一致したらループを抜け終了するプログラムをCで書きたいと思っています。 他のプログラムでも使いまわし、かつ見やすくするためにこの部分を関数化したいのです。ソースにはbreakを使っているのですが、当然ながらbreakはforかwhile内で使わないとダメだと思いますが、ソース作成の都合上、for文は関数内に入れたくないのです。 (つまり、条件分岐を関数化したものをfor文内で用いたい) うまい方法が思いつかずに困っています。もし良い方法をお気づきの方がおられたらご助力下さい。 //===============================================// //=================以下ソース====================// //===============================================// //ビット配列correct_ciphertextとPbinを比較するプログラム //LSBからMSBまで順に走査を行い、違うビットが出てきた時点でbreakし、走査を止める //Pbinは固定値を与えている #include <stdio.h> #include <string.h> unsigned int mes[2]; unsigned int key[2]; char Pbin[64]; char Kbin[64]; char ciphertext[64] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0}; void ConvertPtextToBin_ForHost(unsigned int mes[]){ unsigned int tmp_mes[2] = {mes[0], mes[1]}; int i, j; for(j=0;j<=1;j++){ for(i=0;i<=31;i++){ Pbin[j*32 + 31-i] = tmp_mes[j] % 2; tmp_mes[j] = tmp_mes[j] / 2; } } } int main(int argc, char *argv[]){ //initialize mes[0] = 0x00000000; mes[1] = 0x00000000; int i, j, k; int x=0, y=0; while(1){ printf("mes[1] = %d\n", mes[1]); ConvertPtextToBin_ForHost(mes); for(i=0; i<64; i++){ printf("%d", Pbin[i]); if((i+1)%8 == 0) printf(" "); } printf("\n"); //************************* //ビット走査 //************************* for(k=0; k<64; k++){ if( (ciphertext[63-k] == Pbin[63-k]) ){ //同じビットであれば、次のビットを走査する }else{ printf("Error\n");//後ろから走査していって、1ビットでも違うものがあれば違うビット列と判断する break; } } //ここに来たら違うビット列だったということ if(k != 64){ mes[1]++; printf("Not match ciphertext... %dth bit didn't match. (0bit:LSB)\n", k); printf("This was %d*%dth Search...\n\n", y, x); x++; if(x>=65535){i=0; y++;} }else{ //k=64つまり、最後のビットまで同じビットだったということ⇒つまり、「発見」 printf("Match ciphertext\n"); printf("This was %d*%dth Search...\n\n", y, x); break; } //*********************** //ビット走査の終了 //*********************** } }

  • 関数に文字列を渡すことについて

    参考書にあったプログラムなのですが、 ------------------------------------------- #include<stdio.h> void strout(char ss[ ]); int main(void) { char st[ ]="ABCDEF"; strout(st); strout("ABab12"); return 0; } void strout(char ss[ ]) { int i; printf("ss=%s\n",ss); i=0; while(ss[i]){ printf("%X ",ss[i]); ++i; } printf("\n"); } ---------------------------------------------- ------------実行結果--------------- ss=ABCDEF 41 42 43 44 45 46 ss=ABab12 41 42 61 62 31 32 ----------------------------------- 初心者という事で、いろいろと疑問があるのですが、 ◎1「stとして、文字配列をss[ ]に渡すのと、"ABab12"として直接文字列をss[ ]に渡すのはとは、どういうことなのかということ。そしてその時ss[ ]はどうなっているか?」 ◎2「実行結果で、最初のprintfからループさせなくてもss=ABCDEF、ss=ABab12が何故2つとも表示され、2つとも16進数が表示されるのか?」 ◎3「while(ss[i])だけで何故、'\0'でない間ループするという事が出来てしまうのか?」 以上のような疑問があります。 先頭のアドレスを渡すといったような説明はあるのですが、いまひとつ分かりません。 教えていただけると嬉しいです。