• 締切済み

上手く表示できない。(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% (1622/5658)
回答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% (2177/4070)
回答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% (2177/4070)
回答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

  • C言語の質問です

    下記のプログラムは数字の0から9を意味する英単語の文字列テーブルを作成し、それからユーザーに(文字として)数字を入力させ、このテーブルを使って該当する単語を表示するものです #include <stdio.h> #include <conio.h> int main(void) { char digits[10][10] = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" }; char num; printf("数字を入力してください: "); num = getche(); printf("\n"); num = num - '0'; if(num>=0 && num<10) printf("%s", digits[num]); return 0; } num = num - '0' とするのが分かりません。 使っている本には、ヒントとして 『入力された文字から'0'を引けば、テーブルのインデックスが得られます』とありますが、これもよく分かりません。

  • C言語 ソートについて

    #include <stdbool.h> #include <stdio.h> void swap(char *a, char *b) { } bool is_at(char c) { } void justify(char line[], int n) { } int main(void) { char line[] = "a@b@@@c@@d@@@ef@@g"; size_t n = sizeof(line) - 1; justify(line, n); printf("%s\n", line); return 0; } 上の雛形を使って文字列lineに含まれる@以外の文字を文字列の前の方に詰めていくプログラミングを作るという問題を解いていたのですが下のプログラミングまでは出来たのですが最後のjustifyの部分がわかりません 良ければ解答をお願いします #include <stdbool.h> #include <stdio.h> void swap(char *a, char *b) { char temp = *a; *a = *b; *b = temp; } bool is_at(char c) { if(c == '@') { return true; } else { return false; } } void justify(char line[], int n) { for(int i=0;i<n-1;i++) { } } int main(void) { char line[] = "a@b@@@c@@d@@@ef@@g"; size_t n = sizeof(line) - 1; justify(line, n); printf("%s\n", line); return 0; }

  • C言語について

    いつも、お世話になっています。 以下のソースでわからないことがあります。 1.構造体入れ子になっている SCH の代入方法。 2.一覧表示するとき、入れ子になっているSCHの表示方法。 3./*IDの入力後に社員リストからそのIDを呼び出す*/の件ついての考え方。 宜しくお願いします。 #include <stdio.h> #include <string.h> #include <stdlib.h> #include <time.h> #define MAX_NUMBER 100 /* 登録件数 */ #define NAME 30 /* 氏名の文字数 */ #define LINE 100 /* スケジュールの文字数 */ #define NUM 4 /* IDの桁数 */ typedef struct { char SCH[LINE]; /* 予定 */ } work; typedef struct { char ID[NUM]; /* 番号 */ char name[NAME]; /* 氏名 */ work sched; } syain; void namecheck(char* ID) { printf("ID:"); scanf("%s", ID); } void namecheck(char* name) { printf("名前:"); scanf("%s", name); } void syaintouroku(syain data[], int syain_num) { IDcheck(data[syain_num].ID); namecheck(data[syain_num].name); } void sched_touroku(syain data[], int syain_num) { puts("登録するIDを入力してください。"); /*IDの入力後に社員リストからそのIDを呼び出す*/      /*そのIDの方のスケジュールを登録*/ SCHcheck(data[syain_num].work.SCH); } void print_data(syain data[], int syain_num) { for(i = 0; i < MAX_NUMBER; i++){      printf(data[syain_num].ID, data[syain_num].name, data[syain_num].work.ID,); } } int main(void) { syain meibo[MAX_NUMBER]; int max_syain = 0; syaintouroku(meibo, max_syain); max_syain++; worktouroku(meibo, syain_num); print_data(meibo, syain_num) return 0; }

  • C言語のコードについて

    C言語の問題なのですか、作成したのですが内容がわからないです。 コードをわかりやすく解説していただけると嬉しいです。 #include <stdio.h> void printBinary(unsigned char num) { int i ; /*①上位ビットから順に表示する*/ for(i = 7 ; i >= 0; i--) { /*②シフトとマスクを使用しています。*/ printf("%d", (num>>i) &0x01 ); } printf("\n"); } int main(void) { unsigned char num1 = 0xD2;/*11010010*/ unsigned char num2 = 0x5E;/*01011110*/ printf("0xD2 : "); printBinary(num1); printf("0x5E : "); printBinary(num2); return 0; }

  • C言語

    文を繰り返すときに、『続けますか(Y=続行。N=終了)』と表示して、Yが入力されたら文を繰り返すようにしたいのですが、わからないので教えてください。 #include<stdio.h> int main(void) { int m,s,r,num; char moji; num=1; do{ printf("距離を入力してください。\n"); scanf("%d",&m); printf("平均速度を入力してください。\n"); scanf("%d",&s); r=m/s; printf("所要時間は%dです。\n",r); printf("続けますか?(Y=続行。N=終了)\n");/*このあたりがどうすればいいのかわかりません*/ moji=getchar(); }while(num) printf("終了します。\n"); return 0; }

  • C言語のフローチャート

    昨日に引き続き失礼します。下記のプログラムを作成したのですがフローチャートは、どのように書けばいいのでしょうか? #include "stdafx.h" #include <stdio.h> int _tmain(int argc, _TCHAR* argv[]) { char ss[10] = "abcdefg"; char *ssp; ssp =ss; while (1){ if (*ssp ==0) break; printf("文字 *ssp=%c\n",*ssp); ++ssp;} int ary[10] = {1,2,3,4,5,6,7,8,9,10}; int *pt; pt = ary; while (1) { if (*pt == 10) break; printf("値 *pt=%d\n",*pt); ++pt;} return 0; }

  • C言語strcmpについて

    下記のプログラムでstrcmp動かしたところ、理論的には、68と表示されるところ、1と表示される理由を教えてください。詳細部分は、省略します、たとえば、include,const strcmp("ABCDE","ABC"); int strcmp(char *s1,char *s2){ while(*s1==*s2){ if(*s1=='\0') return (0); s1++; s2++; } return(( unsigned char)*s1 - (unsigned char)*s2);  

  • C言語の穴埋め問題です

    次のプログラムは、初期化により文字列を定義し、辞書式配列にしたとき、どの文字列が先頭にくるかを調べるプログラムなのですが。■■■を教えてください #include <stdio.h> #include <string.h> #define N 5 //関数のプロトタイプ宣言 char *min(char *p[] , int n); int main(void) { char *p[N] = {"Hello" , "Hi" , "Happy" , "HaHaHa" , "Heaven"}; printf("辞書式配列で先頭となる文字列は%s\n" , ■■■); } char *min(char *p[] , int n) { int min; //最小値のアドレス Int i; //カウンタ min = 0; for(i = 1; i < n; i++){ if (strcmp(■■■ , ■■■) > 0){ ■■■= ■■■; } } return ■■■; }

  • C言語の問題が解けません!

    僕は、C言語を勉強しているのですがこの問題の答えがわかりません。 どうか教えてください。 回答お願いします。 ・問題・ 10文字以内の2つの英単語を入力し、アルファベット順で最初にくる単語を表示するプログラムを作りなさい。 /プログラム/ #include<stdio.h> #include<string.h> int main(void) { char str1[256],str2[256]; int i; printf("文字列1は?"); printf("文字列2は?"); return 0; }

  • C言語

    今C言語の基本について学習しているのですが… 初心者なのでまったくわかりません。 #include<stdio.h> int main() char *p,*q; char s[27]="abcdefghijklmnopqrstuvwxyz" char h[5]="GHIJK" 【 】 printf("%c"\n,p); printf("%c"\n,q); return(0); } この【 】の中に何がくるのか分かる方がいたらぜひ教えてほしいですm(__)m よろしくおねがいします。

専門家に質問してみよう