
マイコンにて、
C言語で浮動小数点の数値を表示するプログラムを作成しているのですが、
PRINT_OUT("123.456");
のように、文字列を直接指定した場合は正しく表示されるのですが、
sprintf()関数を用いて、浮動小数点を文字列に変換した場合、
buf char[10];
sprintf(buf,"%lf",123.456);
PRINT_OUT(buf);
とした場合はプログラムが暴走?(恐らく配列破壊を起こしていると
思われますが、)してしまい、上手く動作しません。
(但し、整数の場合は正常に動作します。)
そこで、質問させていただきたいのですが、
"123.456"のように直接文字列を指定した場合と、浮動小数点123.456
をsprintf()関数を用いて文字列に変換した"123.456"の書式に何か
違いはあるのでしょうか?よろしくお願い致します。
No.1ベストアンサー
- 回答日時:
> sprintf(buf,"%lf",123.456);
まず、double型の書式指定は %lf ではなく %f です。
%lf を使った場合の動作は未定義ですので、何が起こっても不思議ではありません(C99対応の場合はOKです)。
また、PRINT_OUT関数の仕様が不明ですので、もしかするとそこに原因があるのかもしれません。
参考URL:http://www.kijineko.co.jp/tech/superstitions/pri …
この回答への補足
>>まず、double型の書式指定は %lf ではなく %f です。
>>%lf を使った場合の動作は未定義ですので、何が起こっても不思議では
>>ありません(C99対応の場合はOKです)。
そうだったのですね。%lfが標準だと勘違いしていました。
参考URLが参考になります。ありがとうございます。
>>また、PRINT_OUT関数の仕様が不明ですので、もしかすると
>>そこに原因があるのかもしれません。
PRINTOUT関数をもう少し調べてみます。
No.5
- 回答日時:
H8ですね。
残念ながらルネサスはSH2とR8Cしか経験が無いんで経験からの話は出来なさそうです。結果を見る限り、私もsprintfの浮動小数点の実装が心配ですね。
bufの内容を1バイトづつターミナルに表示させてみてはどうでしょう。
sprintf(buf,"%lf",123.456);
for( i=0; i<20 ; i++ ) {
char dump[10];
sprintf(dump,"%02x:%c\n",buf[i],buf[i]));
PRINT_OUT(dump);
}
こんな感じで。
この回答への補足
>>sprintf(buf,"%lf",123.456);
>>for( i=0; i<20 ; i++ ) {
>>char dump[10];
>>sprintf(dump,"%02x:%c\n",buf[i],buf[i]));
>>PRINT_OUT(dump);
>>}
bufの内容を1文字ずつ表示するこちらの方法も試してみたいと思います。
ご助言、ありがとうございます。
No.4
- 回答日時:
おそらく暴走の原因は#2で指摘されている配列要素数の不足が原因でしょうね。
ただ、書式指定が間違っていると、本当に暴走してしまう実装も組み込みではときどき見かけます。また、sprintf関数自体がフリースタンディング環境ではサポートされないため、浮動小数点数が使えないことも普通にあったりします(浮動小数点周りのランタイムをリンクすると、非常にプログラムサイズが大きくなるので)。
その辺りも問題がないか調べてみてください。
PRINT_OUTに関しては、関数またはマクロの定義をよく調べることと、
char buf[] = "123.456";
PRINT_OUT(buf);
としたときに期待した結果になるかどうかを調べて、問題を切り分けることをお勧めします。
この回答への補足
>>ただ、書式指定が間違っていると、本当に暴走してしまう実装も
>>組み込みではときどき見かけます。また、sprintf関数自体がフリー
>>スタンディング環境ではサポートされないため、浮動小数点数が
>>使えないことも普通にあったりします(浮動小数点周りのランタイムを
>>リンクすると、非常にプログラムサイズが大きくなるので)。
そうですか。書式設定辺りに注意が必要そうですね。
また、確かにライブラリを読み込むとプログラムサイズが一気に大きくなりました。
>>char buf[] = "123.456";
>>PRINT_OUT(buf);
こちらの方法も試してみたいと思います。
ご助言、ありがとうございます。
No.3
- 回答日時:
shirayukixさんへ。
マイコンですのでprintfは実装されていないか、特殊関数を用意しないと使えないと思います。
PRINT_OUT()がUARTを制御していてRS232Cの通信経由でターミナルソフトに文字列を表示する良くある仕組みだと思います。
暴走の原因は、shirayukixさんの言われる通り配列破壊で間違いないでしょう。
linuxbeginnerさんへ。
文字列は、文字列終端'\0'までを含んだ配列サイズを確保してください。
いちいち何文字か気にしているのが面倒であれば余裕を見たサイズで確保しましょう。
名前にLinuxとありますが、Linuxが乗るような32bitマイコンならメモリサイズの余裕があると思いますが。いや、その前にLinuxが乗っているならprintfぐらい使えるようになっているはずだから・・・。もっと小さいマイコンか?
この回答への補足
>>文字列は、文字列終端'\0'までを含んだ配列サイズを確保してください。いちいち何文字か気にしているのが面倒であれば余裕を見たサイズで確保しましょう。
今後は、余裕を持たせて取ることにします。
しかし、今回、サイズを20に変更したのですが、暴走は止まりましたが、
PRINT_OUT()関数で全く表示がされませんので、PRINT_OUT()関数に原因がありそうです。
整数値なら正常に表示されるのが謎ですが。
>>名前にLinuxとありますが、Linuxが乗るような32bitマイコンなら
>>メモリサイズの余裕があると思いますが。いや、その前にLinuxが
>>乗っているならprintfぐらい使えるようになっている
>>はずだから・・・。もっと小さいマイコンか?
使用しているのはH3048という16[bit]のマイコンです。
名前には、Linuxとありますが、これはユーザ登録した当初はLinuxを使って
いたためであり、今回の質問の件とは関係がありません。ややこしくてすいません。
No.2
- 回答日時:
%lfを使うと結果の小数点以下は6桁になります。
123.456000
sprintfでbufに格納すると末尾の'\0'を含めて11文字になりますからbufの長さ10文字を超えます。
なので配列破壊を起こしていると思います。
sprintfを使う前に、printfで出力してみてはどうでしょうか?
この回答への補足
>>%lfを使うと結果の小数点以下は6桁になります。
>>123.456000
>>sprintfでbufに格納すると末尾の'\0'を含めて11文字になりますから
>>bufの長さ10文字を超えます。なので配列破壊を起こしていると思います。
やはり、配列破壊の可能性が高そうですね。
bufのサイズを20に変更した所、暴走はなくなりましたが、
PRINT_OUT関数で全く表示がされていないようです。
>>sprintfを使う前に、printfで出力してみてはどうでしょうか?
これに関しては、マイコン上では、直接指定はできないのですが、
試しにWindows上で試してみたところ、正常に動作はしているみたいです。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
今、見られている記事はコレ!
-
弁護士が解説!あなたの声を行政に届ける「パブリックコメント」制度のすべて
社会に対する意見や不満、疑問。それを発信する場所は、SNSやブログ、そしてニュースサイトのコメント欄など多岐にわたる。教えて!gooでも「ヤフコメ民について」というタイトルのトピックがあり、この投稿の通り、...
-
弁護士が語る「合法と違法を分けるオンラインカジノのシンプルな線引き」
「お金を賭けたら違法です」ーーこう答えたのは富士見坂法律事務所の井上義之弁護士。オンラインカジノが違法となるかどうかの基準は、このように非常にシンプルである。しかし2025年にはいって、違法賭博事件が相次...
-
釣りと密漁の違いは?知らなかったでは済まされない?事前にできることは?
知らなかったでは済まされないのが法律の世界であるが、全てを知ってから何かをするには少々手間がかかるし、最悪始めることすらできずに終わってしまうこともあり得る。教えてgooでも「釣りと密漁の境目はどこです...
-
カスハラとクレームの違いは?カスハラの法的責任は?企業がとるべき対応は?
東京都が、客からの迷惑行為などを称した「カスタマーハラスメント」、いわゆる「カスハラ」の防止を目的とした条例を、全国で初めて成立させた。条例に罰則はなく、2025年4月1日から施行される。 この動きは自治体...
-
なぜ批判コメントをするの?その心理と向き合い方をカウンセラーにきいた!
今や生活に必要不可欠となったインターネット。手軽に情報を得られるだけでなく、ネットを介したコミュニケーションも一般的となった。それと同時に顕在化しているのが、他者に対する辛らつな意見だ。ネットニュース...
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
構造体→文字列→構造体 をする方法
-
C言語 配列の長さの上限
-
BCBで配列の要素数(0)の場合
-
「#undef」と「#define」の使い...
-
char*を初期化したいのですが
-
関数から配列を返すには?
-
C言語において、 配列要素をひ...
-
C++Builder 2009 テキスト...
-
C言語・要素除去
-
Redimした動的配列はEraseする...
-
【速いブラインドタッチ】手を...
-
DXライブラリでの2Dの描画...
-
配列を使わずに、変数名を動的...
-
malloc でのメモリ取得状況の可...
-
c言語のポインタへの文字列入力...
-
メモリ解放について
-
C言語のintとcharの違いってな...
-
辞書式順序
-
CStringからchar*への型変換に...
-
あるディレクトリ内のファイル...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
%dなどの違い
-
nullと""、\\0とEOFの違いにつ...
-
TCL言語で文字列検索方法を教え...
-
C#でstringをポインタとして渡す
-
c#で他のアプリの文字入力フォ...
-
16進数を2文字ずつ配列に格納し...
-
構造体→文字列→構造体 をする方法
-
C++で入力した文字列から数字を...
-
WSH(VBS)でJSONの文字列を読み...
-
バイナリファイル中の日本語文...
-
シリアル通信で0x00を送信した...
-
sprintf関数での文字列変換につ...
-
文字を反転させる。
-
数字の入った配列をファイルへ...
-
C言語のプログラムについて
-
_tcscpy_s(wcscpy_s)の第二引数...
-
char a[]="thank you for comin...
-
プログラムによく出てくるst...
-
VB6.0でのバイナリデータの扱い...
-
C#で質問があります。
おすすめ情報