質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
char

charは文字データ型を指します。一文字分の文字コードの格納を想定としている型です。

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

integer

integerは、一般的に整数を表します。プラスやマイナス、ゼロもなりうる全ての数です。(例 : -2, -1, 0, 1, 2...)

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

3回答

1229閲覧

int型をchar型に変える

Jhon_McClane

総合スコア48

char

charは文字データ型を指します。一文字分の文字コードの格納を想定としている型です。

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

integer

integerは、一般的に整数を表します。プラスやマイナス、ゼロもなりうる全ての数です。(例 : -2, -1, 0, 1, 2...)

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2020/07/10 14:52

前提・実現したいこと

通信の課題です。
読み込んだ10進数の数字文字列を2進数で表した数値8桁に変換しサーバに送信する。
2進数は上位ビットを0でパディングする。

int型をchar型の配列に格納し、sprintfで送るメッセージを完成させたいです。

発生している問題・エラーメッセージ

passing argument 1 of sprintf makes pointer from integer without a cast

該当のソースコード

char binary[8]; read( soc, buf, 1024 );//char型配列で送られてきた数字 x = atoi(buf);//int型に変換し整数値にする //2進数に変換する処理 for( i=0; i<8; i++){ sprintf( binary[i],"%d", x%mypow(2,i+1)/mypow(2,i));//ここでエラー } sprintf(buf,"RESULT %s",binary); int mypow(int base,int index){//指数の計算 int result,i; for( i=0; i<=index; i++ ){ if( i == 0) result = 1; else result = base*result; } return result; }

試したこと

(char)でキャストしたがエラーは回避されなかった。
また、2進数16を整数値のようにint型で1111とあらわそうと考えたが、意味が違ってくると思い作るのをやめました。

補足情報(FW/ツールのバージョンなど)

VirtualBox

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

質問者のソースをある程度生かして書いてみた。
mainがないのでそこは適当にxを即値で設定し、sprintfもprintfにしている。
mypow(2, i)1 << iで計算できるので省略。

C

1#include <stdio.h> 2 3int main(void) 4{ 5 char binary[9]; 6 int x = 127; 7 8 for (int i = 0; i < 8; i++) { 9 int mask = 1 << i; // 2^i の値 10 binary[(8 - 1) - i] = (x & mask) ? '1' : '0'; 11 } 12 binary[8] = '\0'; // 文字列終端 13 14 printf("RESULT %s", binary); 15 return 0; 16}

投稿2020/07/10 15:58

Daregada

総合スコア11990

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Jhon_McClane

2020/07/12 12:17

(x & mask) ここの表現が何をしているのかよく分からないのですが 教えていただけないでしょうか。 3項演算子を使っていることは分かったのですが&当たりが分かりません
Daregada

2020/07/12 12:26

maskは1をiの値だけ上位ビットにシフトしたもので、1, 2, 4, 8, 16, 32, 64, 128の値のどれかになります。2進数の下位から数えた8ビット分の値ですね。 & はビット演算のANDを行なうので、「x の値に maskのビットが立っているか(xを2進表現したさいに、そのビットの値が1かどうか)」を調べることができます。 調べた結果が0でなければ、3項演算子の条件が成立したことになり'1'が、0の場合には条件が不成立で'0'が、binaryの対応する要素に格納されます。
Jhon_McClane

2020/07/12 12:37

ビット演算を書いたことがなかったので勉強になりました。 2進数を考えるときなどはビット演算が使えるとわかりやすいと思いました。
guest

0

まずエラーが出ている部分について指摘すると、sprintf()関数の第一引数は文字配列(文字列)の先頭アドレスを与えるべきなのに文字を与えているのがエラーの原因です。
「binary[i]」→「&binary[i]」と修正すれば一応エラーはなくなると思います。

C

1 sprintf( &binary[i],"%d", x%mypow(2,i+1)/mypow(2,i));

だたし、いくつか問題点があります。
sprintf()は文字配列に対して出力するため、文字列を1文字しか出力しない場合でも末尾に「\0」が付加されてしまいます。処理される内容を擬似的にコードで書くとこんな風に書き込まれる動作になります。

C

1// ループ1回目のsprintf() 2binary[0] = '1'; 3binary[1] = `\0'; 4// 2回目のsprintf() 5binary[1] = '1'; /* ← 直前の'\0'を上書きしている */ 6binary[2] = '\0'; 7() 8// 8回目のsprintf() 9binary[7] = '1'; 10binary[8] = '\0'; /* ← binary配列の領域を越えた位置に書き込んでしまっている */ 11

'\0'をループの次回で上書きしているのがちょっと気持ち悪いです。(動くことは動きますが)
問題なのはループ最後の'\0'の書き込みは配列の領域を越えた位置に書き込んでしまっていることです。

配列binaryは'\0'の領域1バイトを追加したほうが良いです。

char binary[ 8 + 1 ];

sprintf()のままでも動くことは動きますが、2進数文字列を作成する際に文字を直接書いたほうが良い気がします。
最後に末尾の'\0'を入れます。

for( i=0; i<8; i++){ binary[i] = '0' + ( x%mypow(2,i+1)/mypow(2,i) ); } binary[ 8 ] = '\0';

投稿2020/07/10 15:40

hidezzz

総合スコア1248

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Jhon_McClane

2020/07/11 01:51

わかりやすい説明ありがとうございます。原因が分かりすっきりしました。アドレスについてまだ理解が足りてないことが分かりました。 アドレスを渡す際、配列の各要素を指定する際は[&]が必要で、全体を渡す場合、binaryと書くと先頭ポインタが渡されるため【&】をつけないという解釈であっていますか。
hidezzz

2020/07/11 05:05

> アドレスを渡す際、配列の各要素を指定する際は[&]が必要で、全体を渡す場合、binaryと書くと先頭ポインタが渡されるため【&】をつけないという解釈であっていますか。 はいそうです。 1点補足すると、「binary」は「&binary[0]」と同じです。
Jhon_McClane

2020/07/12 12:09

ありがとうございます。勉強になりました。
guest

0

ベストアンサー

はじめにコンパイルエラー等

  • x,iの宣言がない。mainが書かれていないので省略されていると思うがコンパイルエラーになるので回答者に対して不親切。
  • binary[8]はSegmentation faultの危険がある。8文字確保したいならヌル文字分を含めて[9]にしなければならない。

本題

10進数の数値xをn進数の数字列に置き換える定石は、

  • x と n の剰余を求める(x % n)
  • x を n で除算しその整数位を新しいxとする(x = x / n)

を繰り返すことです。
下の桁から求まるので、2進数8桁で求めるならbinary[7]からスタートです。

c

1for(int i = 7; i >= 0; i--){ 2 binary[i] = '0' + (x % 2); // 2で割った余りを代入。このような文字の代入法は覚えておくと役に立つ!! 3 x = x / 2; // x を 2で割る 4} 5binary[8] = '\0'; // 最後にヌル文字を入れるのを忘れずに‼

これなら特に気にすることなく0埋めも可能です。
sprintfもmypowも不要です。

投稿2020/07/10 15:25

hope_mucci

総合スコア4447

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Jhon_McClane

2020/07/10 15:39

解決しました、ありがとうございます。変数で使用した最低限のものは、宣言を書くようにします。ご指摘ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問