ローマ文字への変換

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

ローマ文字への変換

#1

投稿記事 by うしくん » 18年前

OS:Vista コンパイラ:borlandC++

1~4999までの整数を入力してローマ記法に変換するプログラムを作ったのですが、実行すると
的外れの結果になります。0(ゼロ)を入力すると終了するように作ったつもりなのですが、
終了しません。どこが悪いのかまったくわかりません。宜しくお願いします。
また、もっとスマートに作れるのであれば、指摘もお願いします。
#include<stdio.h>

int main(void)
{
	int n=0,m,p,q,r;
	char seisu[5];
	printf("1~4999までの整数を入力してください。\n");
	fflush(stdout);
	while(1)
	{
		printf("Input integer (0 QUIT)====>");
		fflush(stdout);
		scanf("%s",&seisu);
		if(seisu[0]==0)break;
		printf("%s ===> ",seisu);
		fflush(stdout);
		while(seisu[n]!='\0')
		{
			n++;
		}
		p=n-3;
		q=n-2;
		r=n-1;
		if(n==4)		/*千の位*/
		{
			for(m=1;m<=seisu[0];m++)
			{
				printf("M");
			}
			n--;
		}
		if(n==3)		/*百の位*/
		{
			if(seisu[p]>=5)
			{
				printf("D");
				for(m=1;m<=seisu[p]-5;m++)
				{
					printf("C");
				}
			}
			else
			{
				for(m=1;m<=seisu[p];m++)
				{
					printf("C");
				}
			}
			n--;
		}
		if(n==2)		/*十の位*/
		{
			if(seisu[q]>=5)
			{
				printf("L");
				for(m=1;m<=seisu[q]-5;m++)
				{
					printf("X");
				}
			}
			else
			{
				for(m=1;m<=seisu[q];m++)
				{
					printf("X");
				}
			}
			n--;
		}
		if(n==1)		/*一の位*/
		{
			if(seisu[[/url]==9){
				printf("IX");
			}else if(seisu[[/url]>=5){
				printf("V");
				for(m=1;m<=seisu[[/url]-5;m++)
				{
					printf("I");
				}
			}else if(seisu[[/url]==4){
				printf("IV");
			}else{
				for(m=1;m<=seisu[[/url];m++)
				{
					printf("I");
				}
			}
		}
		printf("\n");
	}
	return 0;
}
長い文章ですみません。

box

Re:ローマ文字への変換

#2

投稿記事 by box » 18年前

> 		if(seisu[0]==0)break;

数値の0と数字の'0'とは異なります。

うしくん

Re:ローマ文字への変換

#3

投稿記事 by うしくん » 18年前

ありがとうございます。終了する部分はうまくいくのですがローマ文字への変換がうまくいきません。
もしかしてこれも数値と数字の違いが原因なのでしょうか?

box

Re:ローマ文字への変換

#4

投稿記事 by box » 18年前

私だったら、こんな構造体を作って考えます。


#include <stdio.h>

typedef struct __roman {
	char *romanChar;
	int number;
} Roman;

int main(void)
{
	Roman roman[/url] = {
		{ "I",    1 }, { "IV",   4 }, { "V",   5 }, { "IX",   9 },
		{ "X",   10 }, { "XL",  40 }, { "L",  50 }, { "XC",  90 },
		{ "C",  100 }, { "CD", 400 }, { "D", 500 }, { "CM", 900 },
		{ "M", 1000 },
	};
	
	return 0;
}

box

Re:ローマ文字への変換

#5

投稿記事 by box » 18年前

ちょっとした例を作ってみました。
参考になるとよいのですけれど。


#include <stdio.h>

typedef struct __roman {
	char *romanChar;
	int number;
} Roman;

int main(void)
{
	Roman roman[/url] = {
		{ "I",    1 }, { "IV",   4 }, { "V",   5 }, { "IX",   9 },
		{ "X",   10 }, { "XL",  40 }, { "L",  50 }, { "XC",  90 },
		{ "C",  100 }, { "CD", 400 }, { "D", 500 }, { "CM", 900 },
		{ "M", 1000 },
	};
	int m, n, i;
	
	for (n = 1; n <= 4999; n++) {
		printf("%4d:", n);
		m = n;
		for (i = sizeof(roman) / sizeof(roman[0]) - 1; i >= 0; i--) {
			while (m / roman.number) {
				printf("%s", roman.romanChar);
				m -= roman.number;
			}
		}
		putchar('\n');
	}
	return 0;
}

うしくん

Re:ローマ文字への変換

#6

投稿記事 by うしくん » 18年前

ありがとうございます。参考にしてみます。

うしくん

Re:ローマ文字への変換

#7

投稿記事 by うしくん » 18年前

for (i = sizeof(roman) / sizeof(roman[0]) - 1; i >= 0; i--) {
			while (m / roman.number) {
				printf("%s", roman.romanChar);
				m -= roman.number;
			}
		}


この部分がいまいちよくわかりません。
解説をしていただけないでしょうか?特にforとwhileの条件式のところが
よく理解できません。お願いします。

box

Re:ローマ文字への変換

#8

投稿記事 by box » 18年前

>		for (i = sizeof(roman) / sizeof(roman[0]) - 1; i >= 0; i--) {

sizeof(roman) / sizeof(roman[0]) は、構造体の配列 roman[/url] の
要素数です。有効な添字の最大値は(要素数-1)です。
このforループでは、roman[/url] の要素を後ろから順にたどります。

>			while (m / roman.number) {

ローマ数字に変換したい数値 m を、1000, 900, 500, ..., 5, 4, 1 の順に
割ります。商が正ならば、m は割った数以上の値を持ちます。
ただし、例えば 1000 で割るとき、1 回だけ割って終わり、というわけではありません。
割れなくなるまで繰り返す必要があります。そのために、while 文による
ループを構成しています。

>				printf("%s", roman.romanChar);

割った数に対応するローマ数字を出力します。

>				m -= roman.number;

ローマ数字を出力した分を除く必要があります。

たかぎ

Re:ローマ文字への変換

#9

投稿記事 by たかぎ » 18年前

> typedef struct __roman {

二重の下線で始まる識別子は予約済み識別子ですので使用することは出来ません。
本題からは外れますが、真似する人がいるといけないので、念のため指摘しておきます。

box

Re:ローマ文字への変換

#10

投稿記事 by box » 18年前

> 二重の下線で始まる識別子は予約済み識別子ですので使用することは出来ません。

あ、そうでしたか。
後学のために、どのように修正すればよいか
教えていただけますか?

box

Re:ローマ文字への変換

#11

投稿記事 by box » 18年前

下線で始まり、下線または大文字が続く識別子は予約済とのことですので、

typedef struct roman {

あたりで十分のようです。
どうもお騒がせいたしました。

うしくん

Re:ローマ文字への変換

#12

投稿記事 by うしくん » 18年前

分かりやすい丁寧な解説をありがとうございます。
boxさんのを参考にして作ってみたらできました。
自分が作ってたのよりとてもスマートに出来ました。
#include <stdio.h>

typedef struct __roman {
	char *romanChar;
	int number;
} Roman;

int main(void)
{
	Roman roman[/url] = {
		{ "I",    1 }, { "IV",   4 }, { "V",   5 }, { "IX",   9 },
		{ "X",   10 }, { "XL",  40 }, { "L",  50 }, { "XC",  90 },
		{ "C",  100 }, { "CD", 400 }, { "D", 500 }, { "CM", 900 },
		{ "M", 1000 },
	};
	int  n, i;
	printf("------------ OUTPUT -----------\n");
	fflush(stdout);
	while(1)
	{
		printf("Input integer (0 QUIT)====>");
		fflush(stdout);		
		scanf("%d",&n);
		if(n==0)break;
		for (i =sizeof(roman) / sizeof(roman[0]) - 1; i >= 0; i--)
		 {
			while (n/roman.number)
			 {
				printf("%s", roman.romanChar);
				n -= roman.number;
			}
		}
		putchar('\n');
	}
	printf("------------- END -------------\n");
	return 0;
}


ありがとうございました。

うしくん

Re:ローマ文字への変換

#13

投稿記事 by うしくん » 18年前

更新していなかったので気づきませんでした。
下線は消しておきます。
ありがとうございました。

閉鎖

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