C実践プログラミングの問題

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
まじかる

C実践プログラミングの問題

#1

投稿記事 by まじかる » 9年前

オライリーのC実践プログラミングの実習8-6「数字で表した数値を英文で表したものに変換するプログラムを作成してください。たとえば895はeight nine fiveとなります。」

という問題でプログラムを以下のように書いたのですが、うまく動作しません。
どうやら配列にうまく数字が入っていないようなのですが・・・・・・

ご教授よろしくお願いいたします。

(なお、桁数は5桁までとしています。)

コード:


#include <stdio.h>

int bekijou(int *p,int n){	//桁数を計算し、配列に数値を格納する関数

	int counter=1;	//桁数
	int number_10=1;	//10の巾乗

	while(1){
		n=n/10;
		if(n==0)
			break;
		counter++;
	}

	for(int i=counter;i>0;i--){
		for(int j=0;j<counter-1;j++){
			number_10 *=10;
		}
		*(p+i)=n/number_10;
		number_10=1;
	}

	return counter;
}

int main(void){

	int input_number;	//最初に入力する数値
	int keta;	//桁数
	int num[5]={0};	//それぞれの桁の数値を格納
	int i;	//for文用

	printf("5桁までの数字を入力してください\n");
	scanf("%d",&input_number);

	keta=bekijou(num,input_number);	//桁数を計算

	for(i=0;i<keta;i++){
		switch(num[i]){
			case 1:
				printf("one ");
				break;
			case 2:
				printf("two ");
				break;
			case 3:
				printf("three ");
				break;
			case 4:
				printf("four ");
				break;
			case 5:
				printf("five ");
				break;
			case 6:
				printf("six ");
				break;
			case 7:
				printf("seven ");
				break;
			case 8:
				printf("eight ");
				break;
			case 9:
				printf("nine ");
				break;
			default:
				;
		}
	}
	printf("\n");

	return 0;
}


アバター
shiro4ao
記事: 224
登録日時: 9年前
住所: 広島

Re: C実践プログラミングの問題

#2

投稿記事 by shiro4ao » 9年前

「数字で表した数値を英文で表したものに変換するプログラムを作成してください。」
という動作のみなら以下のコードで出来るかもしれません。
(WinVista BorlandC++Cimpikerにて動作確認)

なぜ、配列に数字が入らないのかはわかりませんでした。
力にならなくてすみません。

コード:


#include <stdio.h>
 #include <string.h>
#include <stdlib.h>

int bekijou(int *p,int n){  //桁数を計算し、配列に数値を格納する関数
 
    int counter=1;  //桁数
    int number_10=1;    //10の巾乗
 
    while(1){
        n=n/10;
        if(n==0)
            break;
        counter++;
    }
 
    for(int i=counter;i>0;i--){
        for(int j=0;j<counter-1;j++){
            number_10 *=10;
        }
        *(p+i)=n/number_10;
        number_10=1;
    }
 
    return counter;
}
 
int main(void){
 
    int input_number;   //最初に入力する数値
    int keta;   //桁数
    int num[5]={0}; //それぞれの桁の数値を格納
    int i,n;  //for文用
    char buf[6],c[2];   //文字として数字を扱うためのバッファ
    printf("5桁までの数字を入力してください\n");

    //数値を文字列として受け取る
    gets(buf);
    strcat(buf,"\0");
    
    
    //この関数は戻り値のみを利用する(numを使ってない)
    keta=bekijou(num,atoi(buf)); //桁数を計算
 
    for(i=0;i<keta;i++){
	memcpy(c,&buf[i],1);        //連続した文字から、指定した桁の部分の文字を取り出す
	strcpy(&c[1],"\0");          //末尾にヌル文字を加える

        switch(atoi(c)){                 //指定桁数の部分の文字を数字へ変換し判定する
            case 1:
                printf("one ");
                break;
            case 2:
                printf("two ");
                break;
            case 3:
                printf("three ");
                break;
            case 4:
                printf("four ");
                break;
            case 5:
                printf("five ");
                break;
            case 6:
                printf("six ");
                break;
            case 7:
                printf("seven ");
                break;
            case 8:
                printf("eight ");
                break;
            case 9:
                printf("nine ");
                break;
        }
    }
    printf("\n");
 
    return 0;
}


アバター
パコネコ
記事: 139
登録日時: 9年前
住所: 大阪

Re: C実践プログラミングの問題

#3

投稿記事 by パコネコ » 9年前

全部読んだわけではないので何か勘違いがありましたらすいません。

コード:

*(p+i)=n/number_10;
は0確定ですがあってますか?
正確にはnが0だってことですが・・・
最初のwhileに入る前にnの値をコピーすることをお勧めします。

=追加=
今読み終わりました。
0も描写しましょう。
===
他にも問題があるようです。


===
一応書きなおしました

コード:

.
みるかどうかはあなた次第。
わからないところは書いといてください。








.
int bekijou(int *p,int n){  //桁数を計算し、配列に数値を格納する関数
	int counter=0;  //桁数
	int number_10=1;    //10の巾乗
	int i,j,a,b;

	//桁数を計算する
	for(i=n;i!=0;i/=10)
		counter++;

	//配列に放り込む
	b=n;
	for(i=counter-1;0<=i;i--){
		a=b;
		for(j=0;j<i;j++)
			a/=10;
		*(p+i)=a;
		for(j=0;j<i;j++)
			a*=10;
		b-=a;
	}
	return counter;
}
//ちなみに0を入力されたときの対策は抜いてます。
この関数でうごくはず・・・
ニャン!!\(゜ロ\)(/ロ゜)/

まじかる

Re: C実践プログラミングの問題

#4

投稿記事 by まじかる » 9年前

shiro4ao様、パコネコ 様

お返事いただきましてありがとうございます。

これから仕事なので、ソースコードをじっくり見る時間は今ありませんが、
帰宅次第かならずチェックのうえ、返信いたします。

ISLe
記事: 2648
登録日時: 9年前
連絡を取る:

Re: C実践プログラミングの問題

#5

投稿記事 by ISLe » 9年前

剰余(%演算子)を使ってはいけないのですか?

maru

Re: C実践プログラミングの問題

#6

投稿記事 by maru » 9年前

超手抜き版。

コード:

// 適切なヘッダファイルをインクルードする。
int _tmain()
{
	char s[10];
	int	n;
	scanf("%d", &n);
	sprintf(s, "%d", n);
	for (char* p = s; *p != 0; ++p)
	{
		switch (*p)	
		{
			case '0':	printf("zero ");	break;
			case '1':	printf("one ");	break;
			case '2':	printf("two ");	break;
			case '3':	printf("three ");	break;
			case '4':	printf("four ");	break;
			case '5':	printf("five ");	break;
			case '6':	printf("six ");	break;
			case '7':	printf("seven ");	break;
			case '8':	printf("eight ");	break;
			case '9':	printf("nine ");	break;
			default:	assert(0);
		}
	}
	printf("\n");

	return 0;
}
こういうことではないですよね。

まじかる

Re: C実践プログラミングの問題

#7

投稿記事 by まじかる » 9年前

ようやく帰ってきたので、早速皆様のコードを読ませていただきました。
皆様どうもありがとうございます。

>shiro4ao様、maru様

文字列を数値に変換する方法で問題を解いたわけですね。
しかしsprintfは便利な関数です。

>ISLe様

剰余を使うということ自体に気づきませんでした。
たしかに、剰余を使うと関数内が簡単に処理できそうです。

たとえばa=525の2を取り出すには

(a%100)/10などとすればよさそうですね。

>maru様

このプログラミングが私のやろうとしていたことです!
しかし、読めばわかりますがこれはなかなか自分で書けといわれてもかけないです・・・・・・

あとは自分でもう少しコードを精査してみようと思います。
皆様本当にありがとうございました。

box
記事: 1748
登録日時: 9年前

Re: C実践プログラミングの問題

#8

投稿記事 by box » 9年前

switch ~ case にこだわりすぎ。
もっとシンプルに書ける。

コード:

#include <stdio.h>
#include <ctype.h>

int main(void)
{
    char s[6];
    char *p;
    char *n[] = {
        "zero", "one", "two",   "three", "four",
        "five", "six", "seven", "eight", "nine",
    };

    scanf("%s", s);     // バッファーオーバーフローはノーチェック
    for (p = s; *p; p++) {
        if (isdigit(*p)) {
            printf("%s ", n[*p-'0']);
        }
    }
    putchar('\n');
    return 0;
}
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

閉鎖

“C言語何でも質問掲示板” へ戻る