• ベストアンサー

■int型の数値から数字文字への変換について

はじめまして。専門学生のhide1978と申します。 今回、以下のような問題に取り組んでいるのですが、どうしても正しい結果が得られません。どなたか知恵を授けてやってください。よろしくお願いいたします。 ■問題 int型の数値(-32767から32767)を入力して、そのまま10進文字列(char型)として変換する。 ■私が書いたプログラム #include <stdio.h> int NUMtoCHAR(int c){ if(c >= 0 && c <= 9) return (c+'0'); else return c; } void main(void){ signed int i_value; int count, i; double f_value; char c[9]; printf("入力データ:");scanf("%d",&i_value); printf("\n"); for(i = 0; i < 9; i++) c[i] = ' '; if(i_value > 0){ c[0] = '+'; }else if(i_value < 0){ c[0] = '-'; } f_value = (double)i_value; count = 0; while(f_value >= 1){ f_value = f_value / 10.0; count++; } if(count == 0){ c[2] = '0'; }else{ for(i = 2; count > 0 && i < 9; count--, i++){ f_value = f_value * 10.0; i_value = f_value; c[i] = NUMtoCHAR(i_value); f_value = f_value - i_value; } } printf("10進文字 = "); for(i = 0; i < 9; i++) printf("%c", c[i]); printf("\n"); } 上記プログラムを実行して、入力データとして[32767]を入力すると、結果が[32766]となってしまいます。同じように[34]を入力すると[33]という結果になります。 elseの中に入れ子になっているfor文が怪しいということまでは判るのですが、どのように修正してよいか判りません。 大変長い質問で恐縮ですが、よろしくお願いいたします。 ■環境 OS:WindowsXP Compiler:Borland C++ 5.5.1 fowWin32

質問者が選んだベストアンサー

  • ベストアンサー
  • takebou
  • ベストアンサー率43% (27/62)
回答No.1

入力した数字の桁数を数えた後、f_valueはどうなっていますか? 整数と浮動小数の共存では丸め込みなど行われますので 正確な計算ができくなることは多々あります。 せっかくですから、デバッガの使い方を覚えてf_valueをモニタしながらステップ実行してみましょう。 簡単に整数をcharに変換するには、sprintf関数を使うことです。

hide1978
質問者

お礼

早速の回答ありがとうございます。 なるほど・・・丸め誤差が原因だったんですね。知識としては理解していたつもりなんですが、気がつきませんでした。 実際に、for文内にある i_value = f_value; の下に printf("%d\n", i_value); を挿入し、入力として[32767]を与えて実行してみたところ、[7]と表示されるべき最後の桁が[6]と表示されていました。 あと、教えていただいたsprintf関数を使って見たいのですが、私が持っている書籍にはsprintf関数に関する記述が無く、どのように使用してよいのかわかりません。ネットでも検索してみたのですが、どのサイトも中級者以上を対象に書かれていて、初心者の私には理解できませんでした。 今回のプログラムで以下のような実行結果を得たい場合には、sprintf関数をどのように使えばよいのでしょうか。 ■入力として[-32768]を与えた場合の実行結果 入力データ:-32768 10進文字列 = - 32768 追加質問で申し訳ありませんが、暇なときにでも簡単なサンプルを添えて教えていただけると大変あり難いです。よろしくお願いいたします。m(__)m

その他の回答 (2)

  • takebou
  • ベストアンサー率43% (27/62)
回答No.3

sprintfは、printfの拡張の関数です。 hide1978さんのプログラムにあてはめると、 sprintf( c, "%+d", i_value ); と書けばOKです。 printfの書式の第一引数に文字列を格納するための char型配列を配置すれば良いだけです。

hide1978
質問者

お礼

お返事が遅れて申し訳ありません。 教えていただいた書式を参考に新しくプログラムを組みなおし、何とか目的にかなうプログラムを組むことが出来ました。 今回の質問で新しい発見がいくつもありました。ご回答いただいたtakebouさんとuyama33さんには大変感謝しています。本当にありがとうございました。m(__)m

  • uyama33
  • ベストアンサー率30% (137/450)
回答No.2

sprintf については、 ボーランドの統合環境のヘルプで キーワード検索 として キーワードのタグ を選んで sprintf として 検索すれば 書式、などがでてきます。  または、別売りの マニュアル(高価です) もあるのではないでしょうか? もし、ヘルプがインストールしてなかったら 追加でインストールしてください。

hide1978
質問者

お礼

回答ありがとうございます。お礼が遅くなって申し訳ありません。 ヘルプの件ですが、残念ながら私が使っているのはフリーの[Borand C++ 5.51 for win32]ですからヘルプは付属していません。sprintf関数に関しては、もう少し自分で調べてみようと思います。ありがとうございました。m(__)m

関連するQ&A

  • C言語 文字列の操作

    文字Cが含まれる個数を求めたいです #include <stdio.h> int str_chnum(const char str[],int c) { int i; int count=0; for(i=0;str[i]!="\0";i++) if (str[i]==c) count++; return(count); } int main(void) { char st[100]; printf("検索文字列を入力してください:"); scanf("%s",st) ; printf("検索文字列数は%uです。\n",st,int str_chnum(const str[],int c)); return(0); } コンパイルできません。なぜですか?printfの行がたぶん間違っていると思うんですが。。。

  • C言語文字数4つカウント

    こんにちは。大学の課題で「キーボードから入力した文字数に含まれる'h''o''g''e'の4つの文字数をカウントする関数を含むプログラムを完成させよ」という課題がありました。なかなかできず現段階では以下のようになっています。どうすれば問題文のように実行できますか? #include <stdio.h> char str_chnum(const char str[], int ch) { int count = 0; int i; for(i = 0; str[i] != '\0'; i++) { if(str[i] == ch) count++; } return(count); } int main(void) { char str[128]; int ch; printf("文字列を入力してください:"); scanf("%s", str); printf("検索する文字を入力してください:"); scanf(" %c", &ch); printf("%cは%d個ありました。\n", ch, str_chnum(str, ch)); return(0); }

  • char型+char型ってint型? if(char型==int型)?

    C言語の「汎整数拡張(インテグラルプロモーション)」というものに関するものだと思います。 char型とchar型を加えた結果は、char型でしょうか。それともint型でしょうか。 (下のプログラムの printf("sizeof(a[0]+a[1])は%d\n", sizeof(a[0]+a[1])); /* char型+char型 */ という部分の結果は4なので、int型と考えるべきなのかな。) 私は、char型とint型の加算の結果はint型だと思っていましたが、 char型とchar型の加算の結果はやはりchar型だと思っていました。 (それが間違えているのでしょうか。) if(a[0]==i) /* char型とint型の比較(?) */ の部分では、左辺はchar型、右辺はint型ですが、このように型の違う変数を比較しても文法上構わないのでしょうか。 (私は、「比較は必ず型の同じもの同士でしかできない」と思っていました。) 左辺はchar型のように見えて、じつはint型ですか。 #include <stdio.h> int main(void) { char a[4]; int i=77; printf("sizeof(int)は%d\n", sizeof(int)); printf("sizeof(char)は%d\n", sizeof(char)); printf("sizeof('M')は%d\n", sizeof('M')); printf("sizeof(a[0])は%d\n", sizeof(a[0])); a[0]='M'; a[1]=7+6; a[2]=a[0]+a[1]; printf("sizeof(a[0]+a[1])は%d\n", sizeof(a[0]+a[1])); /* char型+char型 */ printf("sizeof(+a[0])=%d\n", sizeof(+a[0])); if(a[0]==i) /* char型とint型の比較(?) */ puts("a[0]==i"); else puts("a[0]!=i"); return(0); } ちなみにワーニングもエラーもなんにもでません。

  • 二分法のプログラムについて

    下の用なプログラムを作ったのですがどうしても正しい答えを導くことができません。自分でもいろいろ調べてみましたがわかりません。誰かご教授宜しくお願いします。 #include<stdio.h> #include<stdlib.h> #define MAX 10 int n , count; double c[MAX+1]; double a,b,e; void nyuuryoku(void) { int i; printf("nの入力>"); scanf("%d",&n); if(n>MAX){printf("最大次数を超えている");exit(1);} else if(n<0){printf("nが負");exit(2);} else{for(i=0;i<=n;i++){printf("係数の値>");scanf("%lf",&c[i]);} }} double f(double x) {double y; int i; y = c[0]; for(i=1;i<=n;i++){ y=y*x+c[i];} return y; } void hani(void){ printf("aの値>");scanf("%lf",&a); printf("bの値>");scanf("%lf",&b); printf("eの値>");scanf("%lf",&e); if(e<=0){printf("eが0または負"); exit(3);} if(f(a)==0){printf("%f",f(a)); exit(4);} if(f(b)==0){printf("%f",f(b)); exit(5);} if(f(a)*f(b)>0){printf("初期値異常"); exit(6);}} double nibun(void) {double c; if(b>a){ while(b-a>e){ count++; c=(a+b)/2; if(f(c)==0){ return c;} if(f(a)*f(c)<0){b=c;} if(f(b)*f(c)<0){a=c;} } return a;} if(a>b){ while(a-b>e){ count++; c=(a+b)/2; if(f(c)==0){ return c;} if(f(b)*f(c)<0){a=c;} if(f(a)*f(c)<0){b=c;} } return a;} } void syutsuryoku(double x){ printf("x=%lf\n",x); printf("f(x)=%lf\n",f(x)); printf("繰り返し回数=%d\n",count); } int main(void){ double ans; count=0; nyuuryoku(); hani(); ans = nibun(); syutsuryoku(ans); }

  • 文字列の入力、数値変換について

    入力された数字を数値に変換するプログラムを作ったのですが、うまくいきません。 #include <stdio.h> #include <stdlib.h> #include <math.h> #include <string.h> #include <ctype.h> unsigned long long atollu(char[16]); void main(void){ unsigned long long input; char str[16]; char test[16] = "123456789012345"; int i,j=1; //atollu の動作確認・・・(1) printf("atollu test:%llu\n\n",atollu(test) ); //入力 NG: printf("%d回目 数値を入力(1~100000000000000 終了:exit)>",j); gets(str); input = atollu(str); //str と atollu(str) の確認 printf("%s %llu\n\n",str,atollu(str)); //exitと入力すると終了・・・(2) if(strcmp(str, "exit") == 0){ exit(0); } //数字以外がないか確認・・・(3) else { for( i=0; i<=15; i++){ if(isdigit(str[i]) == 0){ printf("NG\n"); for( i=0; i<=16; i++){ str[i]='\0'; } printf("moji\n"); j++; goto NG; } } } //範囲外 if(input>100000000000000 || input==0){ printf("NG\n"); printf("hani\n"); j++; goto NG; } printf("\n入力値は% llu",input ); } unsigned long long atollu(char str[16]){ unsigned long long t=0; int i,n; n = strlen(str) - 1; for( i=0; i<=15; i++){ if(str[i] == '\0'){ str[i] = 0;} else { t = t + (str[i] - '0') * pow(10.0,n-i);} } str[16] = '\0'; return t; } /* 数字を数値に変換する関数atolluは自分で作りました。 これの動作は(1)でちゃんとした値が出ているのでうまくできているようです。 (2)も"exit"と入力すれば終了するのでうまくいっています。 また、例えば "12" と入力したとき 12 9 NG moji 表示されますが、二回目以降は 12 12 NG moji となり、atollu(str)はうまく出力されている一方で、最後に「moji」と出てきているので、(3)でうまくいっていないようです。 どう直すべきなのか見当もつかないので困っています。 よろしくお願いします。

  • アルファベットを入力するとすべてのアルファベットを小文字に変換して出力

    アルファベットを入力するとすべてのアルファベットを小文字に変換して出力するプログラムを作成しました。2度以上同じ処理を行う場合はその部分を関数としなければいけないのですが、実行結果のように出力できませんでした。。どこが間違っているのでしょうか? 実行結果↓ ************ AOmori ==>aomori iwate ==>iwate AKITA ==>akita ************ #include <stdio.h> #include <string.h> #include <ctype.h> int henkan(void); int main(void) { char str[100]; int j,len; for(j=0;j<6;j++){ gets(str); printf("==>"); } henkan(); return 0; } int henkan(void) { char str[100]; int i, chk,len; for(i=0;i<len;i++){ chk=isupper(str[i]); if(chk!=0)str[i]=tolower(str[i]); { printf("%c",str[i]); } } printf("\n"); return chk; }

  • ポインタ文字列をchar[ ]の文字列へ変換する方法

    C言語の問題で悩んでいます。 ポインタ型で受け取った文字列を、通常の配列に変換し、それぞれの文字列がいくつ使われているというプログラムを組みたいのですが、うまくいきません。 とりあえずここまでのソースを。 #include <stdio.h> int count[95]={0}; void Countx(void){ int x; for(x=0;x<=95;x++){ if(count[x]!=0){ printf("'%c': %d\n",x+32,count[x]); } } } void County(char *str){ int c; for(c=0;c<=20;c++){ count[c+32]=str[c]; } } int main(void){ County("I am a BILL."); Counxt(); return 0; } "I am a BILL"の部分が以下のように ' ':3 '.':1 'a':2 というふうにそれぞれの文字と、利用された回数を出すようにプログラムを組みたいのですが、上記のままだとが ' ':84 '!':104 '"':105 と言う風に、文字コードが空白から順番に、右の回数の部分はなぞの数字が表示されてしまいます。 どうか理想どおりの結果が出るようにする方法を教えてください。 よろしくお願いします。

  • char型からint型への変換

    char型からint型への変換 char a[6]=3+2-5; int e[6]; (全て0で初期化済) for(i=0;i<6;i++){ if(c[i]=='0'||c[i]=='1'||c[i]=='2'||c[i]=='3'||c[i]=='4'||c[i]=='5'){ e[i]=((int)c[i]-'0'); printf("%d",e[i]); }} for(i=0;i<NUM_DATA;i++){ printf("%d",e[i]); } このプログラムでは上のe[]の出力では「325」と出力されますが、 下のe[]の出力ではめちゃくちゃな数字が出力されてしまいます。 きちんと数字だけを抽出しint型に変換するにはどうしたらいいでしょうか? C言語で行っています。よろしくお願いします。

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

  • 文字の数値化 関数化

    文字を入力されたとき、数値入力を促す関数を作りたいのですが、 最初の文字が文字ならエラーメッセージがちゃんと出るのですが、 最初の文字が数字ならエラーメッセージが出てくれません。 アドバイスお願いいたします。 tew2 ← エラー出る 2test ← エラー出ない #include <stdio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> float ss_input(void); int main(){ int i; int pop; printf("何人の入力しますか(3人以内)->"); do{ pop=ss_input(); if(pop >3) printf("3人以内でお願いします\n"); }while(pop<1 || pop>3); return 0; } float ss_input(void){ char p[100]; float st; int i=0; scanf("%s",p); while( p[i] != '\0'){ if(isdigit(p[i])==0){ printf("数値を入力してください->"); scanf("%s",p); continue; } else{ break; } } st=atof(p); return st; }

専門家に質問してみよう