4桁の連番に1桁のチェックディジットを付加して5桁のコードを生成したい

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
P387
記事: 10
登録日時: 1年前

4桁の連番に1桁のチェックディジットを付加して5桁のコードを生成したい

#1

投稿記事 by P387 » 1年前

閲覧ありがとうございます。大学の課題で分からなかったので質問させていただきました。初めてこの掲示板を利用するので説明が分かりにくい部分があると思いますがよろしくお願いします。


[問題]
手続codeMakeは、商品の開発順に割り振られた連番を基に5桁の商品コードを生成する。
手続codeMakeは、引数として整数型の変数numberに連番を受け取って生成した商品コードを文字型の一次元配列codeに格納する。
手続codeMakeでは、4桁の連番に1桁のチェックディジットを付加して5桁の商品コードを生成する。 なお、引数として受け取った連番が0以下又は1万以上であった場は、商品コードを “00000" とする。
配列 codeに格納される商品コードの構成を図1に示す。
download/file.php?mode=view&id=2567&sid ... c0d76bad2f

手続codeMake で利用するチェックディジットは、次の手順で求める。
(1) 連番を構成する各桁の数値に重み付けをした総和を求める。 各桁の重みは千の位の数値が4、百の位の数値が3、十の位の数値が2、一の位の数値が1である。連番 (3815) から重み付け総和を求める例を図2に示す。
download/file.php?mode=view&id=2573

(2) 重み付け総和(43)を10で除算した剰余をチェックディジットとする。上記の例の場合、チェックディジットは3となる。


[プログラム]
〇codeMake(整数型:number,文字型の配列:code)
整数型: i, j, base,sum
文字型の配列: D← {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}
if ((numberが0以下) or (numberが10000以上))
number←0
endif
sum←0
base←1000
for (iを1から4まで1ずつ増やす)
j ← number÷base
code←D[j]
sum←sum+j×(5-i)
number←number mod base
base←base÷10
endfor
code[5]←D[sum mod 10+1]


(上のプログラムを元に自分で書いたプログラム)

コード:

#include <stdio.h>
main()
{
char d[10]={'0','1','2','3','4','5','6','7','8','9'},code[5];
int  i,j,base,sum,number;

printf("number?");
scanf("%d",&number);

if(number<=0||number>=10000){
number=0;
}
sum=0;
base=1000;

for(i=0;i<=4;i++){
	j=number/base;
	code[i]=d[j];
	sum=sum+j*(5-i);
	number=number%base;
	base=base/10;
	printf("%c",code[i]);
    }
	code[5]=d[sum%10+1];
}
(実行結果)
number? 3815
3815

38153と表示させたいです。ですが、チェックディジットが付加されず入力した数字がそのまま返されてしまいます。


初心者なので間違いだらけのプログラムですが、ご教授いただければ幸いです。
添付ファイル
134063.jpg
134063.jpg (38.79 KiB) 閲覧数: 11962 回

アバター
幸尚
記事: 47
登録日時: 2年前
連絡を取る:

Re: 4桁の連番に1桁のチェックディジットを付加して5桁のコードを生成したい

#2

投稿記事 by 幸尚 » 1年前

コード:

main()
{
	char d[10] = { '0','1','2','3','4','5','6','7','8','9' };
	char code[5];
	int  i, j, base, sum, number;

	memset(code, '\0', sizeof(code));

	printf("number?");
	scanf("%d", &number);

	if (number <= 0 || number >= 10000) {
		number = 0;
	}
	sum = 0;
	base = 1000;

	for (i = 0; i < 4; i++) {
		j = number / base;
		code[i] = d[j];
		sum = sum + j * (5 - i);
		number = number % base;
		base = base / 10;
		printf("%c", code[i]);
	}
	code[4] = d[sum % 10 + 1];
	printf("%c", code[4]);
}
こうじゃないですかね?

コード:

	for (i = 0; i <= 4; i++) {
上だったら

コード:

	j = number / base;
ここで0を0で割ってるのであり得ないと言って例外が発生します。

また、for分抜けた後に最後の文字を出力してます。

コード:

	printf("%c", code[4]);
あと、一番最初に

コード:

memset(code, '\0', sizeof(code));
でcodeを初期化してます。
ボールを違うところに投げてたらご指摘して頂けると嬉しいです(o_ _)o

アバター
幸尚
記事: 47
登録日時: 2年前
連絡を取る:

Re: 4桁の連番に1桁のチェックディジットを付加して5桁のコードを生成したい

#3

投稿記事 by 幸尚 » 1年前

改良版です。

コード:

main()
{
	char code[6];
	int  i, j, base, sum, number;

	memset(code, '\0', sizeof(code));

	printf("number?");
	scanf("%d", &number);

	if (number <= 0 || number >= 10000) {
		number = 0;
	}
	sum = 0;
	base = 1000;

	for (i = 0; i < 4; i++)
	{
		code[i] = 48 + (number / base);
		number %= base;
		sum += code[i] * (5 - i);
		base /= 10;
	}

	code[4] = 48 + sum % 10 + 1;
	printf("%s", code);
}
数字をアスキーコードに変換してcodeの配列に入れるように修正しました。

また、最終桁数が5桁になるのでNULL文字合わせてcode[6]にしました。
出力は最後に一気に出力するように修正しました。
ボールを違うところに投げてたらご指摘して頂けると嬉しいです(o_ _)o

アバター
幸尚
記事: 47
登録日時: 2年前
連絡を取る:

Re: 4桁の連番に1桁のチェックディジットを付加して5桁のコードを生成したい

#4

投稿記事 by 幸尚 » 1年前

更に
連番が0以下又は1万以上であった場は、商品コードを “00000" とする。
上記仕様を満足するように以下のように修正しました。

コード:

	if (number <= 0 || number >= 10000) {
		memset(code, '0', 5);
		printf("%s", code);
		return 0;
	}
ボールを違うところに投げてたらご指摘して頂けると嬉しいです(o_ _)o

P387
記事: 10
登録日時: 1年前

Re: 4桁の連番に1桁のチェックディジットを付加して5桁のコードを生成したい

#5

投稿記事 by P387 » 1年前

幸尚様

ご回答ありがとうございます。
改良もしてくださり勉強になります!

早速試させていただいたのですが、エラーで「未定義の関数 'memset' を呼び出した(関数 main() )」と出てしまいます。intに付け足せばいいのかと思い足すとエラーで「 関数でないものを呼び出している(関数 main() )」と出てしまいます。
何か解決方法をご存知でしたら教えてくださると嬉しいです。

コード:

#include <stdio.h>
main()
{
	char code[6];
	int  i, j, base, sum, number,memset;

	memset(code, '\0', sizeof(code));

	printf("number?");
	scanf("%d", &number);

	if (number <= 0 || number >= 10000) {
		number = 0;
	}
	sum = 0;
	base = 1000;

	for (i = 0; i < 4; i++)
	{
		code[i] = 48 + (number / base);
		number %= base;
		sum += code[i] * (5 - i);
		base /= 10;
	}

	code[4] = 48 + sum % 10 + 1;
	printf("%s", code);
}

アバター
幸尚
記事: 47
登録日時: 2年前
連絡を取る:

Re: 4桁の連番に1桁のチェックディジットを付加して5桁のコードを生成したい

#6

投稿記事 by 幸尚 » 1年前

#include <string.h>

上記をインクルードすると解決します。

もしそれでだめなら

#include<stdlib.h>

上記に置き換えてください。
ボールを違うところに投げてたらご指摘して頂けると嬉しいです(o_ _)o

box
記事: 2002
登録日時: 14年前

Re: 4桁の連番に1桁のチェックディジットを付加して5桁のコードを生成したい

#7

投稿記事 by box » 1年前

48
とかっていう謎の即値をかくより
'0'
とかってかく方が
可読性が高くなるような気がしないでもない。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

アバター
幸尚
記事: 47
登録日時: 2年前
連絡を取る:

Re: 4桁の連番に1桁のチェックディジットを付加して5桁のコードを生成したい

#8

投稿記事 by 幸尚 » 1年前

そうですね、その方が可読性もあって良いかもしれませんね。
ご指摘ありがとうございます。
ボールを違うところに投げてたらご指摘して頂けると嬉しいです(o_ _)o

アバター
幸尚
記事: 47
登録日時: 2年前
連絡を取る:

Re: 4桁の連番に1桁のチェックディジットを付加して5桁のコードを生成したい

#9

投稿記事 by 幸尚 » 1年前

ということで最終的なソースは以下になります。

コード:

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

main()
{
	char code[6];
	int  i, j, base, sum, number;

	memset(code, '\0', sizeof(code));

	printf("number?");
	scanf("%d", &number);

	if (number <= 0 || number >= 10000) {
		memset(code, '0', 5);
		printf("%s", code);
		return 0;
	}
	sum = 0;
	base = 1000;

	for (i = 0; i < 4; i++)
	{
		code[i] = '0' + (number / base);
		number %= base;
		sum += code[i] * (5 - i);
		base /= 10;
	}

	code[4] = '0' + sum % 10 + 1;
	printf("%s", code);
}
ボールを違うところに投げてたらご指摘して頂けると嬉しいです(o_ _)o

P387
記事: 10
登録日時: 1年前

Re: 4桁の連番に1桁のチェックディジットを付加して5桁のコードを生成したい

#10

投稿記事 by P387 » 1年前

幸尚様・box様

ご回答ありがとうございます。

最終的に示していただいたもので意図した通りに動かすことができました!
長い間悩んでいたので、とても助かりました…!
本当にありがとうございました!

box
記事: 2002
登録日時: 14年前

Re: 4桁の連番に1桁のチェックディジットを付加して5桁のコードを生成したい

#11

投稿記事 by box » 1年前

ところで
手続codeMakeは、商品の開発順に割り振られた連番を基に5桁の商品コードを生成する。
って書いてあるので、codeMakeっていう関数を書く必要があると思うのですが、ここは大丈夫ですか?
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

P387
記事: 10
登録日時: 1年前

Re: 4桁の連番に1桁のチェックディジットを付加して5桁のコードを生成したい

#12

投稿記事 by P387 » 1年前

box様

返信が遅くなって申し訳ございません。

先生の方からこんな感じで書け、と指示されたときに特にcodemakeについての関数は書いてなかったので大丈夫だと思われます。

お気遣いいただきありがとうございました!

アバター
幸尚
記事: 47
登録日時: 2年前
連絡を取る:

Re: 4桁の連番に1桁のチェックディジットを付加して5桁のコードを生成したい

#13

投稿記事 by 幸尚 » 1年前

今後のために残しておきます。

コード:

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

void codeMake(char code[], int number)
{
	int i;
	int sum = 0;
	int base = 1000;

	if (number <= 0 || number >= 10000) {
		memset(code, '0', 5);
		return 0;
	}

	for (i = 0; i < 4; i++)
	{
		code[i] = '0' + (number / base);
		number %= base;
		sum += code[i] * (5 - i);
		base /= 10;
	}
	code[4] = '0' + sum % 10 + 1;
}

int main()
{
	char code[6];
	int number;

	memset(code, '\0', sizeof(code));

	printf("number?");
	scanf("%d", &number);

	codeMake(code, number);
	printf("%s", code);

	return 0;
}
ボールを違うところに投げてたらご指摘して頂けると嬉しいです(o_ _)o

返信

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