• 締切済み

10進数の2進数文字列変換

10進数の2進数文字列変換 ◆開発環境 OS:Linux(Ubuntu9.10) コンパイラ:gcc4.4 言語:C ◆質問内容 ポインタ*Aに格納されている10進数を2進数の文字列に変換し、 文字配列Bに格納したい。 バッファとして*fpを準備。 webで調査した結果を以下のソースのようにアレンジしましたが、 fputc関数の処理で、プログラムが強制終了してしまいます。 何か、良い方法ございませんでしょうか。 ◆サンプルソース void Dec_conv_bit(long *A,char *B){ unsigned int bit,n; //ビット比較用 unsigned int *fp = &n; n = (unsigned int)A; for(bit = 1 << sizeof(int)*8-1; bit > 0; bit >>= 1){ fputc((n & bit)?'1':'0',fp); } sprintf(B,"%s",fp); //putchar('\n'); }

noname#107905
noname#107905

みんなの回答

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.10

いや, 「ビット『列』の逆転」を勝手に「ビットの逆転」と勘違いしただけではないかと>#9. まあ, どんな値で試したのかには, 私も興味がありますが.

  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.9

> ’1’:’0’ → ’0’:’1’ 外れ。 三項演算子・ビット演算・Cにおける真偽値あたりも理解できてなさそうな感じですね。 というかどんな値で試したんですか?

noname#107905
質問者

補足

三項演算子 -> ?’真(1)’:’偽(0)’ ですね。 よくわかってませんでした。 試した値は'204'です。 いろいろ考えているのですが、どうも「ビット列の逆転」が実現できません。(いま、’102’という値で検討中) 甘えついでに、何かヒントをご教授いただけませんか?

回答No.8

ん?まてよ 宣言を途中に書けない規格だったらまずいですね。 その場合一行にこだわるとこういうことになりましたか int i=32; for ( ; i--; A>>=1 ) B[i]=(A&1)+'0'; …微妙w あと手癖で書いてしまいましたが、int i(32);の表記はたしかC++からでしたね すみません その辺直せばC90あたりでも大丈夫だったかな?

回答No.7

// #6 char c[33]; c[32]=0; → char a[33]; a[32]=0;

回答No.6

面白そうなので私も考えてみました。 もしポインタでなくてもいいならこう書くことも可能です。 void Dec_conv_bit(long A, char *B){ for (int i=32 ; i--; A>>=1 ) B[i]=(A&1)+'0'; } ザ、無意味に一行コーディング♪ B[i]→ B[31-i]にしてみると…(略 おそらくアセンブリレベルで得してる要因があるため n2201makitaさんのコードの方が私のPCでは若干速いです。 速度を求めたいなら、小さい数字だった場合途中以降手抜き出来る機能があってもいいですね void Dec_conv_bit(long A, char *B){ int i(32); for ( ; A; A>>=1 ) { B[--i]=(A&1)+'0'; if (!i) return; } memset(B,'0',i); } 今度は保証付きでmemsetが日の目を見られるかな。 実はどっか未定義動作になってたらどなたか指摘してください(笑) 限界まで大きい数字だとif(!i) というのが逆に無意味になりますがw 改良はできると思いますw D-Matsuさんやn2201makitaさんのように、質問内容の表記に忠実に、ポインタを使用しつつ 手抜き機能を組み合わせるということも可能でしょう。 その辺はお好きなようにカスタマイズしてください。 >バッファとして*fpを準備。 ポインタとしてバッファを用意するということは char* fp=(char*)malloc(サイズ); しといて後で free(fp); みたいな感じの意味にとれる文ですが これだけ単純な場合はn2201makitaさんのように普通の配列で良いと思いますし、むしろそっちのがいいと思います。 もし32桁全部表示じゃなくて、それより上は全部0になる場合は表示しない (例: 15→1111 )とかだったら、返り値替えてもち~と面白くすることも出来ます。 #include <stdio.h> char * Dec_conv_bit(long A, char *B){ if (!A) return "0"; int i(32); for ( ; A; A>>=1 ) { B[--i]=(A&1)+'0'; if (!i) return B; } return B+i; } int main(){ char c[33]; c[32]=0; const char *p=Dec_conv_bit(0xe3e3e3f1, a); puts(p); Sleep(3000); }

回答No.5

// #2 #include <stdio.h> void Dec_conv_bit(long *A, char *B){ ○○int i; ○○unsigned bit = 0x80000000; ○○for(i=0; i<32; i++){ ○○○○B[i] = (*A & bit) ? '1' : '0'; ○○○○bit >>= 1; ○○} } int main(){ ○○char a[32+1] = {0}; ○○long b = 0xe3e3e3f1; ○○Dec_conv_bit(&b, a); ○○puts("21098765432109876543210987654321"); ○○puts(a); }

  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.4

あー、#2そのままだとビット列が逆転しますね。 まぁそこは修正しないでおきます。理解できれば直すのは簡単ですから。

noname#107905
質問者

お礼

回答ありがとうございました。 ビットの逆転、理解しました。 ’1’:’0’ → ’0’:’1’ であってますよね?(’0’:’1’にしたら希望通りのビット配列になりました)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.3

うう~ん....「普通」と思える行が 1つもない.... なんでこんな謎を作れてしまうんだろう!? #1 の通りなんだけど, それとは別にアドバイス: このプログラムをコンパイルするときに警告は出ませんでしたか? 絶対に出てると思うんだけど, もし万が一にでも出てなかったらこれからはコンパイルするときに「全ての警告を報告する」オプション (gcc なら -Wall) を必ず付けてください. そして, 1つでも警告が出たら「警告はエラーの根本原因」あるいは「親の敵」とばかりにつぶしていってください. なお, 「型が合わない」という警告に対して「キャストする」というのは (どうにもならないこともあるけど) 邪道です. 変数の型を直すとかロジックを見直すかしてください. 「警告が全く出なくなって, ようやく意味のあるプログラムができるんだ」くらいに思うといいかもしれません.

  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.2

「型」に対する理解が根本的に足りていないか間違っています。 そもそも目的を達成するにはこれで充分のはず。 int bit; for(bit = 0; bit < sizeof(long) * 8; bit ++) { B[bit] = ((*A) & (1 << bit)) & '1' : '0'; } 「どこかで見つけたソースを理解もしようとせずにつぎはぎ」するからそのような変なコードになるんです。 ちゃんと理解して使いましょう。

noname#108260
noname#108260
回答No.1

fpって整数型なのにファイルポインタとしてfputcで使ってるからおかしいんじゃないですか? sprintfの使い方も何か変だし。 全然おかしいですよ。ちゃんと処理内容考えて下さい。

関連するQ&A

  • 10進数文字列の変換

    #include <stdio.h> unsigned int chg(char *); main() {      char m[6] unsigned int value; printf("変換する10進数文字列の入力\n"); gets(m); value =chg(m); printf("%d", value); } unsigned int chg(char *p) { unsigned int w; w = 0; while(*p){ w = w * 10 + *p - '0'; p++; } return w; } aを入力すると49が出力されるのですが unsigned int w; w = 0; while(*p){ w = w * 10 + *p - '0'; p++; } の部分の処理なのですが どのように49に変換している のかが今ひとつ分かりません。 どなたかご教授よろしくお願いいたしますm(_ _)m

  • c言語 型変換について

    c言語 型変換について 下記のように文字コードは、unsigned int型('B')をunsigned char 型(str[1] ) 格下げする型変換する規則を教えてください。 *質問ソースプログラム: int main(void) { char str[4]; /* 文字列を格納する配列 */ str[0] = 'A'; /* 代入 */ str[1] = 'B'; /* 代入 */ ・・・・・・ printf("size B %u\n",(unsigned)sizeof('B')); printf("size str[1] %u\n",(unsigned)sizeof(str[1])); * 実行結果 size B 4 size str[1] 1

  • ファイルから文字列を読み出して16進数に変換

    test1.txtというファイルから文字列を読み出して16進数に変換、という処理をしたいのですがうまくいきません。どこがどう悪いのでしょうか?ご教授のほどお願いします。 ---------------------- #include <stdio.h> #include <stdlib.h> #include <string.h> int main(void) { FILE *fp; char *fname = "test1.txt"; char str[100]; int num; fp = fopen( fname, "r" ); if( fp == NULL ){ printf( "%s is not open.\n", fname ); return -1; } while( fgets(str, 100, fp ) != NULL ){ num = strtol(str, NULL, 16); printf( "%s", str ); printf("%x\n", num); //ここでうまく出力されません } fclose( fp ); return 0; } ---------------- ちなみに、test1.txtの中身は以下のようになってます。 44DB4147E6075A92E878EB68C44DD51F 5DCE86622D846BF272215A792AF31A3E 46FF69A29D3DF1D4842461B239256C26

  • 数値を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とするためにはプログラムにどのような処理をすればよいのかわかりませんのでどなたかおわかりのかた解説をお願いします。

  • 8進数文字列を10進数の数値にする方法

    文字列の数値を10進数に変換したいのですが、 頭に0が付くと8進数扱いでエラーになります。 簡単に変換する方法はありますか? my $a = "09"; my $b = int($a); <-- エラー また、8進数は頭に0ですが 2進数はどんな表記方法でしょうか?

    • ベストアンサー
    • Perl
  • 文字列操作(終端と抽出)について

    こんばんは お時間等ございましたら、ご指摘よろしくお願いします。 <背景>メインプログラムからサブプログラムに複数の数値を渡して、     文字列として編集します。     そして、その文字列から特定の文字のみを抽出し、     ファイルに出力したいと考えています。     ※下記にソースイメージを記しました。      ただ、While文の指定がうまくなく、      想定どおり処理を抜けれません。 <質問>サブプログラムでファイルに出力する文字のうち、     抽出する文字と抽出しない文字はランダムで、     メインプログラムから、渡されてきます。     ※文字列の文字数は、     メインから渡され編集した文字数>=ファイルに出力する文字数。     サブプログラムの先頭で出力する文字列の大きさを     指定しているのですが、抽出しない文字があった場合、     抽出しない文字数分ゴミが出力されてしまうのを     防ぎたいと考えています。 <イメージ> #include <stdio.h> void sub( int a, int b, int c, FILE *fp ); int main(){ FILE *fp; fp = fopen("c:\\0511.txt","w"); int a;int b;int c; a = 1; b = 0; c = 1; sub( a, b, c, fp ); fclose(fp); } void sub( int a, int b, int c, FILE *fp ){ int j = 0; char moji[4];char moji2[4]; sprintf(moji,"%d%d%d%s",a,b,c,"\0" ); while( moji[moji[*moji]] != '\0' ){ switch( moji[moji[*moji]] ){ case '1' : moji2[j] = moji[moji[*moji]]; break; case '0' : j -= 1; break; default :;break; } moji[*moji] += 1;j += 1; } fprintf(fp,"%s\n",moji2 ); }// Run-Time Check Failure #2 - Stack around the variable 'moji' was corrupted. もし宜しければ、ご指摘の程よろしくお願いします。

  • 最大10文字の10進数文字を16進数に変換し表示する

    最大10桁の16進数文字を数字の10進数で表示するコードを記述する事は出来たのですが、その逆が、どうしてもうまくいきません。16進数文字を数字の10進数で表示させるコードをベースに何処の箇所を修正すれば10進数文字を16進数に変換出来るのでしょうか?初心者で難しいコードが解らない為、ダラダラとしたコードで申し訳ございません。 また、今、C言語の文字列の勉強をしてる為、いくつか仕様がありますので、宜しくお願いします。 (1)入力された10進数文字を数値の10進数に変換させた後に、16進数の文字として表示させる。 (2)「printf」以外の関数は使用しない。 (3)最後に表示させる時は「%s」を使用する。 ------------------------------------------------- 【最大10桁の16進数文字を数字の10進数で表示】 #include "stdafx.h" #define MEX 10 /*「function」:入力文字された文字数*/ char ToInt( char cInt) { int mal=0; switch (cInt){ case '0': mal=0; break; case '1': mal=1; break; case '2': mal=2; break; case '3': mal=3; break; case '4': mal=4; break; case '5': mal=5; break; case '6': mal=6; break; case '7': mal=7; break; case '8': mal=8; break; case '9': mal=9; break; case 'a': mal=10; break; case 'A': mal=10; break; case 'b': mal=11; break; case 'B': mal=11; break; case 'c': mal=12; break; case 'C': mal=12; break; case 'd': mal=13; break; case 'D': mal=13; break; case 'e': mal=14; break; case 'E': mal=14; break; case 'f': mal=15; break; case 'F': mal=15; break; } return (mal); } /*「function」:位の計算*/ double HexAcc( double n ) { int i; double ans=1; for( i=0; i<n; i++ ){ ans *= 16; } return (ans); } int _tmain(int argc, _TCHAR* argv[]) { int i=0,n=0,j=0,k=0,s=0,m=0; char decimal[ 255 ], ditto[ 255 ],sub[ 255 ]; /*入力されない場合*/ if( argc > 1 ){ decimal[s] = argv[1][i]; } else{ printf("16進数を入力してください。\n"); return 1; } /*subに文字として'\0'を代入*/ for( k=0; k<=128; k++ ){ sub[k] = '0'; } /*入力された文字数を受取る*/ for( i=0; argv[1][i] != '\0'; i++ ){ decimal[i] = argv[1][i]; } decimal[i] = '\0'; /*空白文字のチェック*/ for( i=0; decimal[i] != '\0'; i++ ){ if( decimal[i] != ' ' ){ ditto[n] = decimal[i]; n++; } } /*'\0'を代入(文字列の終端)*/ ditto[n]='\0'; /*「0」から「9」のループ*/ for( n=0; ditto[n] != '\0'; n++ ){ if(( ditto[n] == '0' ) || ( ditto[n] == '1' ) || ( ditto[n] == '2' ) || ( ditto[n] == '3' ) || ( ditto[n] == '4' ) || ( ditto[n] == '5' ) || ( ditto[n] == '6' ) || ( ditto[n] == '7' ) || ( ditto[n] == '8' ) || ( ditto[n] == '9' ) || ( ditto[n] == 'A' ) || ( ditto[n] == 'B' ) || ( ditto[n] == 'C' ) || ( ditto[n] == 'D' ) || ( ditto[n] == 'E' ) || ( ditto[n] == 'F' ) || ( ditto[n] == 'a' ) || ( ditto[n] == 'b' ) || ( ditto[n] == 'c' ) || ( ditto[n] == 'd' ) || ( ditto[n] == 'e' ) || ( ditto[n] == 'f' )){ }else{ printf("エラー\n 16進数以外の文字が含まれております。\n"); return 0; } } /*桁数のループ*/ for( n=0; ditto[n] != '\0'; n++ ){ m = m + 1 ; } /*桁数の判断*/ if( m <= MEX ){ }else{ printf("エラー\n入力文字数は、%d文字以内にしてください。\n",MEX); return 0; } /*subにdittoを代入*/ for( n=0; ditto[n] != '\0'; n++){ sub[MEX-m+n] = ditto[n]; } /*'\0'を代入(文字列の終端)*/ sub[MEX] = '\0';*/ /*「double型:addの初期化」「int型:ans初期化」add・ansの初期化*/ double ans=0; double add=0; /*sub[0]からsub[9]の計算*/ for( n=0; sub[n] != '\0'; n++){ ans = ToInt(sub[n]); add += ans * HexAcc(MEX-n-1); } /*最大10桁の16進数文字を数字の10進数で表示*/ printf("最大10桁の16進数文字を数字の10進数に変換した値は %f \n",add);

  • c言語 文字列と配列

    #include<stdio.h> int charlen(int n); void cap2sml(int b); int main() { char a[100],b[100]; int n,i; /*Input CARACTERS*/ printf("CAPITAL?\n"); fgets(a,100,stdin); charlen(n); printf("total cahrs=%d\n",n); //printf in main cap2sml(i); printf("small=%s\n",b); return(0); int charlen(int n) n=0; while(1){ if(a[n]=='\0') break; n++; } void cap2sml(int b) int i; for(i=0;a[i]!='\0';i++){ b[i]=a[i]+0x20; } b[i]='\0' } のプログラムでエラーがでるのですが、どこを直せばよいでしょうか? ユーザー関数を使い文字列(大文字)を入力したときの文字列の長さと大文字を小文字に変化するプログラムです

  • お願いします、教えてください。10進数を2進数に変換するには・・・。

    10進数を2進数に変換するプログラムを作成したのですが、うまく動作しません、どうしても解らないので教えてください。 サンプルコードを元に「define」は5で稼動出来る様にしたいのですが、動作せず困っています。以下の、どの部分を修正すれば変換出来るのでしょうか? ご教授よろしくお願いいたします。 //10進数文字を数字の2進数で表示 #include "stdafx.h" #define HEX 5 //「function」:入力文字された文字の処理///////////////////////////////////// char ToInt( char cInt) { int mal=0; switch (cInt){ case '0': mal=0; break; case '1': mal=1; break; case '2': mal=2; break; case '3': mal=3; break; case '4': mal=4; break; case '5': mal=5; break; case '6': mal=6; break; case '7': mal=7; break; case '8': mal=8; break; case '9': mal=9; break; } return (mal); } //「function」:入力文字された文字数//////////////////////////////////////////// char HexInt( char eInt) { char mul=0; switch (eInt){ case 0: mul='0'; break; case 1: mul='1'; break; } return (mul); } //「function」:桁数の計算(10×指数を計算)/////////////////////////////////// int HexAcc( int n ) { int i; int ans=1; for( i=0; i<n; i++ ){ ans *= 10; } return (ans); } int _tmain(int argc, _TCHAR* argv[]) { int i=0,n=0,j=0,s=0,k=0,m=0,e=0,ans=0, add=0; char decimal[255], ditto[255],sub[255],temp[255],chg[255],siu[255]; //入力されない場合// if( 1 > argc ){ } else{ printf("10進数を入力してください。\n"); return 1; } for( k=0; k<255; k++ ){ //文字として'0'を代入// sub[k] = '0'; //subに文字として'0'を代入// temp[k] = '0'; //tempに文字として'0'を代入// chg[k] = '0'; //chgに文字として'0'を代入// siu[k] = '0'; //siuに文字として'0'を代入// } //入力された文字数を受取る// for( i=0; argv[1][i] != '\0'; i++ ){ decimal[i] = argv[1][i]; } decimal[i] = '\0'; //空白文字のチェック// for( i=0; decimal[i] != '\0'; i++ ){ if( decimal[i] != ' ' ){ ditto[n] = decimal[i]; n++; } } //'\0'を代入(文字列の終端)// ditto[n]='\0'; //「0」から「9」のループ// for( n=0; ditto[n] != '\0'; n++ ){ if(( ditto[n] == '0' ) || ( ditto[n] == '1' ) || ( ditto[n] == '2' ) || ( ditto[n] == '3' ) || ( ditto[n] == '4' ) || ( ditto[n] == '5' ) || ( ditto[n] == '6' ) || ( ditto[n] == '7' ) || ( ditto[n] == '8' ) || ( ditto[n] == '9' )){ }else{ printf("エラー\n 10進数を入力してください。\n"); return 0; } } //桁数のループ// for( n=0; ditto[n] != '\0'; n++ ){ m = m + 1 ; } //桁数の判断// if( m <= HEX ){ }else{ printf("エラー\n入力文字数は、%d文字以内にしてください。\n",HEX); return 0; } //subにdittoを代入// for( n=0; ditto[n] != '\0'; n++){ sub[HEX-m+n] = ditto[n]; } sub[HEX] = '\0'; //'\0'を代入(文字列の終端)// //sub[0]からsub[9]の計算// for( n=0; sub[n] != '\0'; n++){ ans = ToInt(sub[n]); add += ans * HexAcc(HEX-n-1); } //2進数の計算・商が0になるまで// for( n=0; sub[n] != '\0'; n++ ){ temp[n] = add % 2; add = add / 2; if( add == 0){ break; } } temp[HEX] = '\0'; //'\0'を代入(文字列の終端)// //桁数のチェック(商・余り)// for( ; n>=0; n-- ){ e = e++; } //temp・値の入替え「tempからchg」// for( n=0; sub[n] != '\0'; n++ ){ chg[HEX-n-2] = temp[n]; } chg[HEX]='\0'; //'\0'を代入(文字列の終端)// //2進数に変換// for( ; n>=0; n-- ){ siu[n] = HexInt(chg[n]); } siu[HEX]='\0'; //'\0'を代入(文字列の終端)// printf("\n10進数文字を2進数で変換した値は・・・ %s \n",siu); }

  • 文字列を大文字の2桁ごとのコンマ付き16進数に変換する方法

    文字列を大文字の2桁ごとのコンマ付き16進数に変換する方法がわかりません。ただ単に文字列を16進数に変更するだけならbin2hex()でできますけど、誰か知っている方はいませんか?具体的には、変換された文字列が1a2b3c4d5e6fなら、1A.2B.3C.4D.5E.6Fと変換したいんです。どうすればいいですか?

    • ベストアンサー
    • PHP

専門家に質問してみよう