• ベストアンサー

C言語超初級

はじめまして。 自分は大学入ってからC言語を勉強しています。 授業で課題が出ているのですが難しくてどうすればいいかわかりません。 プロの皆さんには楽勝だと思いますがよろしくおねがいします。 内容 いろいろ計算して出てきた商品価格(例えば1234567円)に位取りのカンマを挿入して表示する関数(int型の最大桁数である10桁の数値まで表示できるようにすること)を作成する。 1234567→1,234,567 見たいな感じです。 自分でも考えたいのでよろしかったら考え方みたいなのをヒントください。 ちなみにこの一ヶ月でならったことは int,float,char,if,for,swhitch,while,scanf,printf,簡単な関数の作り方くらいです。数少ない武器ですがこれらの道具でお願いします。 胸を貸してください。

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

  • ベストアンサー
回答No.11

問題のint型数値がnumberに置数されているものとします。 まず、3桁ごとにx1,x2,x3,x4に分類しましょう。 1)numberを1000000000で割った商をx1に、余りをnumberに格納します。 2)numberを1000000で割った商をx2に、余りをnumberに格納します。 3)numberを1000で割った商をx3に、余りをx4に格納します。 このx1,x2,x3,x4を印刷すればいいのですが、numberに意地のわるい 数字(1とか0)が入っていると困るので、場合分けしましょう。 1)x1,x2,x3が共にゼロのとき   x4を印刷して終了。   この書式は"%d\n"です。 2)x1,x2が共にゼロのとき   x3,x4を印刷して終了。   この書式は"%d,%d\n"です。 3)x1がゼロのとき   x2,x3,x4を印刷して終了。   この書式は"%d,%d,%d\n"です。 4)その他のとき   x1,x2,x3,x4を印刷して終了。   この書式は"%d,%d,%d,%d\n"です。 ね、初心者らしい解き方でしょ!?

kiki28
質問者

お礼

ありがとうございます。 この方法は自分も考え付きました。 ただ最初の値がfloat型だったのであまりを出せませんでした。 でもこねくりまわしたら結果的に表示はできました。 komaさんにはnumberを中継することで定義する関数を減らすことを学びました。ありがとうございます。

その他の回答 (11)

回答No.12

No.11です。 誤文訂正させて! 1)x1,x2,x3が共にゼロのとき   x4を印刷して終了。   この書式は"%d"です。 2)x1,x2が共にゼロのとき   x3,x4を印刷して終了。   この書式は"%d,%03d"です。 3)x1がゼロのとき   x2,x3,x4を印刷して終了。   この書式は"%d,%03d,%03d"です。 4)その他のとき   x1,x2,x3,x4を印刷して終了。   この書式は"%d,%03d,%03d,%03d"です。 先頭以外の%dは、全部%03dに変更です。(^^;

  • nano_cat
  • ベストアンサー率24% (26/106)
回答No.10

No.9です。感激していただいて、私も嬉しいです。 特に「今まで習ったものだけを使うように」という 指定がなければ使っていいと思います。 cの関数ライブラリを作る際は、まずsprintfを作って、 これを利用して、printfやfprintfを作るような気が します。 でもsprintfを使わなくても、sprintfと同様に できますよ。 int n; char buf[ 20 ]; n = 1234567; buf[ 0 ] = '0' + n / 1000000; buf[ 1 ] = '0' + ( n - ( n / 1000000 ) * 1000000 ) / 100000; ・・・・・ などのように。nの大きさに注意しないといけません。 (上の例はnは7桁と仮定しています。8桁以上だと うまくいきません。6桁以下ならば'0'が頭にくっつ いてしまう。問題は最大10桁だから、10桁でやって、 10桁未満の時の頭の'0'は取るようにすることも できる。) forループで回せばエレガントです。

kiki28
質問者

お礼

ありがとうございます。 これだと入れ替えることができますね。 でも今回は100ずつかえて割ったほうが懸命みたいですね。 またの機会に使わせていただきます。きっと使う日が来ると思います。 そのときはよろしく(?)

  • nano_cat
  • ベストアンサー率24% (26/106)
回答No.9

sprintf という関数があります。 printfの頭にsが付いたもの。 printfは画面に出力しますが、 sprintfは文字配列に出力します。 (他にfprintfというのもあります。これはファイルに 出力します。) これを使えば文字として扱えます。 int n; char buf[ 20 ]; n = 1234567; sprintf( buf, "%d", n ); としますと、 buf[ 0 ] に、'1'、 buf[ 1 ] に、'2'、 buf[ 2 ] に、'3'、 buf[ 3 ] に、'4'、 buf[ 4 ] に、'5'、 buf[ 5 ] に、'6'、 buf[ 6 ] に、'7'、 buf[ 7 ] に、'\0' が入ります。 文字列の長さを調べて(strlenという関数があります) 後はテキトーに。

kiki28
質問者

お礼

うおおー・・ sprintf ってすごいですね! そうですよ、これがしたかったのです。これをしなくてもできるみたいですけど。 しかし・・くっ・・・!使っちゃいけないのかな? 使ってもいいと思いますか?習ってないのですが。 算数みたいです。後になればすぐできる公式があるのに今は使うなみたいな。いいのかな? ありがとうございました!

noname#30727
noname#30727
回答No.8

>int,float,char,if,for,swhitch,while,scanf,printf これだけを使って表示させるには、文字配列に、右側から1文字ずつ書き込んでprintfで一括表示させるか、再帰的に左から1文字ずつ表示させるかのどちらかが簡単だと思います。 再帰は習っていないと思いますが、実は再帰の方が簡単なので、あえて再帰で書いてみます。多少の参考にはなると思います。 ちなみに、負数の最小値を指定するとちゃんと表示できません(笑 #include <stdio.h> void display(int n, int d) { if (n < 0) { printf("-"); n = -n; } if (n >= 10) { display(n / 10, d + 1); } printf("%d", n % 10); if (d && d % 3 == 0) { printf(","); } } int main() { int n; printf("intput: "); scanf("%d", &n); display(n, 0); printf("\n"); return (0); }

noname#16581
noname#16581
回答No.7

頭の桁がいくつあるかとそのあとの3桁がいくつあるかを考えて、「,」を挿入していきます。 一文字づつ別のchar型にコピーしていけばいいと思います。 あまり他の回答者さんのようにエレガントではないですが。 慣れれば、他のやり方も見つかると思います。 回答そのものですが、以下ソース #include<stdio.h> #include<string.h> int main() { int Num=1234567890; int Keta=1; char Str0[128];int m=0; char Str1[128];int n=0; sprintf(Str0,"%d",Num); while(Num/10!=0){Num/=10;Keta++;} int a=Keta%3; int b=Keta/3; if(a!=0) { strcpy(&Str1[n],&Str0[m]); n+=a; m+=a; Str1[n]=',';Str1[n+1]='\0'; n++; } for(int i=0;i<b;i++) { strcpy(&Str1[n],&Str0[m]); n+=3; m+=3; if(i<b-1) { Str1[n]=',';Str1[n+1]='\0'; n++; } } printf(Str1); getchar(); return 0; }

kiki28
質問者

お礼

たくさん打っていただきありがとうございます。 まだよんでませんがどうもポインタを使ってるみたいですか? 若干苦しいプログラムです。ごめんなさい。 また勉強したらしっかり読もうと思います。

  • EUR
  • ベストアンサー率61% (29/47)
回答No.6

たびたびすみません。 No1さんの回答に対して質問者さんが書いた「回答に関する補足」に対する補足ですが、 課題は表示を行えばいいとのことなので、printfのみで結果を表示することが出来ます。 No2さんのprintfの仕様を見てみましょうというのは、うまくprintfを用いれば、ループなどまわす必要もなく、すんなりと表示してくれるよ、と言う意味だと思います。 例、 printf("abc"); → abc と表示される char str[4] = "def"; pringf("%s", str); → def と表示される int num = 123; printf("%d", num); → 123 と表示される char str[4] = "ghi"; int num = 456; printf("%s%d", str, num) → ghi456 と表示される char str[4] = "jkl"; int num = 789; printf("%s何か挟んでみる%d", str, num) → ghi何か挟んでみる456 と表示される という感じです。

kiki28
質問者

お礼

あ、確かに。でも10桁指定のプログラムっぽくて微妙な印象を受けてしまいます。 %sって%cと一緒でしたよね?・・・自分で調べます、このくらいは。 下記のものを読ませてもらい分かりましたが。 分からないときは1234567を1と234と567に分ける方法が思いつきませんでした。 あれですね、あまりの道具を完璧に忘れてました。 これならできそうです。たびたびアドバイスありがとうございます。

  • 5S6
  • ベストアンサー率29% (675/2291)
回答No.5

#include <stdio.h> #include <string.h> void kanma(char *s) {   int count;   int i;   int len;   len = (int) strlen(s);   count = len % 3;   if (count == 0)     count = 3;   i = 0;   for (;;) {     putchar(s[i]);     i++;     if (i == len)       break;     count--;     if (count == 0) {       putchar(',');       count = 3;     }   } } メインは省略したけど、これがヒント。 ほとんど答えそのものだけど。 割り算もあるけどこういう方法もあります。 この場合桁制限を受けません。 int -> char変換は itoa使うとか sprintf 使うとか。 このくらい調べましょう。 割り算でもOKですよ。 プログラムわからないのは仕方ないとしても、アルゴリズムが考えられないと まずいですよ。

kiki28
質問者

お礼

まずいですか・・・才能ないんでしょうね(笑) 凡人なので大目に見てください。 atoi は知ってましたが逆もあったのですね。発見です。 この場合、アドレスはどうなっているのでしょうか? アドレスであってるのかな?先生は箱って言ってます。

  • EUR
  • ベストアンサー率61% (29/47)
回答No.4

おっとすみません、sprintfは武器に入っていませんでしたね。 でも、表示するだけならprintfでOKですね。

kiki28
質問者

お礼

あ、すみません。これ見てませんでした。

  • EUR
  • ベストアンサー率61% (29/47)
回答No.3

sprintf、商、余りを用いると出来ますよ。 int sho = (int)(a / b);//商を求める int amari = (int)(a % b);//余りを求める 1.数字を1000000で割った商をA、余りをBとする 2.Bを1000で割った商をC、余りをDとする 1234567でたとえると、 1234567を1000000で割った商は1、余りは234567 234567を1000で割った商は234、余りは567 後はsprintfを使えば簡単ですね。

kiki28
質問者

お礼

ありがとうございます。 なんかできそうな感じですが sprintf を知りません。 どういった機能を持つ関数なのですか? でも % は知ってました。これは道具に使えます。 後配列もつかえました。

  • 6dou_rinne
  • ベストアンサー率25% (1361/5264)
回答No.2

printfの仕様を見てください。

kiki28
質問者

補足

仕様とはなんでしょうか? もうちょっとヒントお願いします。ごめんなさい。

関連するQ&A