• 締切済み

上手く表示できない。(C言語)

お世話になります。capeofdragonと申します。 Visual Studio 2008 ProでC言語を書いたのですが、 上手く表示されません。 やりたいことは、 256と言う、int型の値を、十分の一倍し、 25.6 と言う、文字列に置き換えて、 文字列として表示させることです。 以下にソースを添付します。 #include "stdafx.h" #include <stdio.h> #include <stdlib.h> #include <string.h> char *ftoa(int num) { char Num[10]; char rNum[10]; char decimal1[1]; char integer[2]; _itoa_s(num, Num, 10); integer[0] = Num[0]; integer[1] = Num[1]; decimal1[0] = Num[2]; if(integer[0] == '0') { rNum[0] = integer[1]; rNum[1] = '.'; rNum[2] = decimal1[0]; return rNum; } else { rNum[0] = integer[0]; rNum[1] = integer[1]; rNum[2] = '.'; rNum[3] = decimal1[0]; return rNum; } } int _tmain(int argc, _TCHAR* argv[]) { char *pWk; int a = 256; pWk = ftoa(a); printf("pWk = %s\n",pWk); return 0; } コンパイルすると、 pWk =  と表示され、 pWk = 25.6 と表示されません。 また、sprintfを使いたいのですが、 高速化のために、キャラクター操作とかけ算、シフトレジスタなどだけで シンプルに作成したいと考えています。 お手数をお掛け致しますが、 ご教授宜しくお願い致します。

みんなの回答

  • wormhole
  • ベストアンサー率28% (1626/5665)
回答No.9

>終端文字'\0'分の領域まで確保していないと、理解しています。 それだけじゃないですが。 それがわかってないからまた同じ事してるし(他の方も指摘されてますが) まともにプログラムが組めないレベルで高速化などを考えたところでろくな事はありません(実は遅速化だったりまともに動かなかったり)。 前にもいいましたが勉強をしっかりやり直した方がいいです。 どうでもいいですが一番高速な方法書いておきましょうか // valは0~1000限定 const char *ftoa(int val) { static const char *numtbl[] = { "0.0", "0.1", "0.2", ~ "99.9", "100.0", } return numtbl[val]; }

回答No.8

itoaは使っていいけどsprintfは使っちゃダメって、なんかチグハグな気がするのは私だけ? 実数を使わないっていう制約なら int _tmain(int argc, _TCHAR* argv[]) { int a = 256; char pWk[10]; sprintf(buffer, "%d.%d", a/10, a%10); printf("pWk = %s\n",pWk); return 0; } でもいいでしょうね。 関数化するなら、グローバル変数にするんじゃなくて、作成した文字列を格納する領域を呼び出し元から渡すようにするのが良いでしょう。 void my_func(int num, char* buffer) { if (0 <= num && num < 1000) { sprintf(buffer, "%d.%d", a/10, a%10); } else { *buffer = 0; } } nt _tmain(int argc, _TCHAR* argv[]) { int a = 256; char pWk[10]; my_func(a, buffer); printf("pWk = %s\n",pWk); return 0; }

  • Wr5
  • ベストアンサー率53% (2173/4061)
回答No.7

>0の時は、何も表示されませんでした。 >if分を用いて、0の時は、 >0.0 >を表示させるようにして、エラーを回避しました。 でしたら、1の時は? 2の時は? 3の時は?  : 9の時は? 10の時は? という確認はしましたか?

回答No.6

> 実際、計測されるのは、 > 300以下から0以上となります。 では、試しに0の時にあなたの考えた方法で問題が出ないか検証してみましょう。

wnsato
質問者

補足

ご回答有難うございます。 0の時は、何も表示されませんでした。 if分を用いて、0の時は、 0.0 を表示させるようにして、エラーを回避しました。 ご指摘有難うございます(^^)。

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

引数は 100以上 (1000未満) に限定してるんだっけ?

wnsato
質問者

補足

1000未満を想定しています。 実際、計測されるのは、 300以下から0以上となります。 これを例えば、 300なら30.0に、 196なら19.6に、 25なら、25.0に、 表示したい、 と考えています。

  • Wr5
  • ベストアンサー率53% (2173/4061)
回答No.4

>最後の「また」以降が何を意味するのかさっぱり分からん. sprintf()相当(低機能版?)の、いわゆる「車輪の再発明」かと…。 # strchr()相当の…ってのならやったことはありますけどねぇ。 # ShiftJISでの問題回避の為。とはいえ、いまのCランタイムで対応しているとは思いますけどね。(ロケールの設定とか必要かもしれませんが) 下手に「高速化だ~」とか「シンプル版だ~」とかやって無意味にバグを盛り込むリスクを負うよりは、 既存のライブラリ使った方がマシでしょう。 # 先の通り、再発明することもたまにありますけどね……。 本来の問題点については既に指摘回答ついていますのであえて回答はしませんが。 >char decimal1[1]; とか >decimal1[0] = Num[2]; とか、ちょっと……。 # 言語仕様的にはありなんでしょうけど。

回答No.3

文字列終端の\0を入れる処理も抜けてますから、変数をグローバルにすれば解決というわけにはいかないでしょう。 ちゃんと勉強しなおすことをお勧めします。

  • neKo_deux
  • ベストアンサー率44% (5541/12319)
回答No.2

プログラムを実行すると、 > int _tmain(int argc, _TCHAR* argv[]) > { > char *pWk; pWkという変数名で、char型のポインタ変数が確保されます。 > int a = 256; > pWk = ftoa(a); 256の値を引数として、ftoa関数が呼び出されます。 ftoa関数の中では、 > char *ftoa(int num) > { > char Num[10]; > char rNum[10]; ~様々な処理をした結果~ > return rNum; で、関数内のローカル変数のアドレスを返しています。 この際、関数内のローカル変数の内容やアドレスは、関数から抜けた際に保証が無くなります。 そのため、かつては関数内のローカル変数の値を指していたが、mainに戻った後はなんだか分からないアドレスを、 > printf("pWk = %s\n",pWk); として表示しようとした結果、(運良くセグメンテーション違反なんかにならずに)何も表示されないって状態になっているって事だと思います。 -- 取りあえず動作すればって対処法だと、 char rNum[10]; を関数の中から出して、ソースの先頭に持って来てグローバル変数にしてしまえば、動作するハズ。 (対処の方策としては、最悪の部類ですが…。) -- C言語の最大の難関、ポインタの所で説明や理解は難しいところですが、 デバッグの方法としては、 char rNum[10]; の直後に、 printf("rNum[10]のアドレスは%x\n", rNum) printf("rNum[0]の内容は%c\n", rNum[0]) などとして、ポインタ変数=アドレスを入れる変数って事で、何番地のアドレスが入っていて、そのアドレスに格納されている値は?とかを意識するってのが、自分の場合は分かりやすかったです。

wnsato
質問者

お礼

ご回答有難うございます。 グローバル変数を用いるのは不本意でしたが、 ご回答を参考にして、作った所、 本意の表示が出来ました。 short型を受け取って、 小数点第一までの実数表記の文字列配列を、 表示させる関数に、文字列配列の変数を入れて、 表示させたかったと言う、背景があります。 extern void _kPutTextXY(short ACol,short ARow,short AColor,short char *AStr) { textcolor(AColor); gotoxy(ACol+1.ARow+1); cprintf("%s",AStr); } と言う、関数がありまして、 _kPutTextXY(pCol,Row,pColor,pWk) のpWkの場所に、グローバル変数のrNumを入れることで、 動作しました。 本来なら、sprintfなどで、pWkに実数の文字列を、入れれば良いのですが、 実数は用いない仕様になっており、 sprintf(pWk,"%.1f A",stChnl[pCnt].mMesCurrent); とすると、エラーになります。 stChnl[pCnt].mMesCurrentはshort型の値。 丁寧なご対応有難うございました。 自分なりに、もう一度良い方法ないか確かめてみます。 また、何かありましたら、宜しくお願い致します。

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

最後の「また」以降が何を意味するのかさっぱり分からん. とりあえず http://okwave.jp/qa/q7416900.html の #4 で何を言われたか, 理解できていますか?

wnsato
質問者

補足

回答有難うございます。 終端文字'\0'分の領域まで確保していないと、 理解しています。

関連するQ&A