課題ができません;誰かアドバイスを!

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

課題ができません;誰かアドバイスを!

#1

投稿記事 by がんも » 18年前

課題で、プログラムを作ったのですが、どこが間違ってるのかわかりません;
ぜひ教えてください。

(問題)

関数char3plus() とstr rev()(←この2つの関数は前の問題で作りました),および文字列の長さを返すライブラリ関数strlen() を引用して,str plus() を作成せよ.
ただし,その最初の行を:void str plus(char s1[/url], char s2[/url], char s3[/url])
とする.この関数を引用すれば,2 個の文字列s1 とs2 に対して,両者の和を表わすs3 が得られると
する.例えば,s1 とs2 がそれぞれ”2134” と”81” であれば,s3 には”2215” が入る.ただし,文字
列の長さはs1 の方がs2 より長いとする.
(ヒント)まず適当な大きさの文字配列t1,t2,t3 を用意し,このうちt1 とt2 にそれぞれs1 とs2
を反転した文字列を入れる.また,それぞれの文字列の長さn1 とn2 を(strlen() を用いて)得る.次
に,t1 とt2 の和を(繰り上げも考慮して) t3 に入れる操作を,i=0,1<=i<n2,n2<=i<n1
の各場合に分けて順に行ない,最後の繰り上げを処理したうえでt3 の反転をs3 に入れる.


(プログラム)
#include<stdio.h>

void str_rev(char s[/url], char t[/url])
{
int i = 0, n, k;

while(s != '\0')i++;

k = i;

for(n = 0; n < k; n++)
{

i--;

t[n] = s;

}


}

void char3plus(char a0, char a1,char a2, char *b0, char *b1)
{
char n;

n = a0 - '0' + a1 - '0' + a2 - '0';

*b0 = n/10 + '0';

*b1 = n%10 + '0';

}


void str_plus(char s1[/url], char s2[/url], char s3[/url])
{
char t1[100] = "\0", t2[100] = "\0", t3[100] = "\0", k0, k1;
int n1, n2, i;


n1 = strlen(s1);

n2 = strlen(s2);

str_rev(s1,t1);

str_rev(s2,t2);

for(i = 0; i < n1; i++){

if(i = 0) char3plus(t1,t2,0,&k0,&t3);

else if(i >= 1 && n2 > i) char3plus(t1,t2,k1,&k0,&t3[i]);

else char3plus(t1[i],0,k1,&k0,&t3[i]);

k1 = k0;

}

str_rev(t3,s3);

}



int main(void)
{
char s1[100], s2[100], s3[100] = "\0";

scanf("%s %s", s1, s2);

str_plus(s1, s2, s3);

printf("%s\n",s3);

}




実行しようとすると、
文字列を2つ入力するととまってしまいます;;

miyaza

Re:課題ができません;誰かアドバイスを!

#2

投稿記事 by miyaza » 18年前

まず、最初にstrlen()を使うためにstring.hをインクルードして下さい。
コンパイル時に警告はでませんでしたか?

がんも

Re:課題ができません;誰かアドバイスを!

#3

投稿記事 by がんも » 18年前

警告でませんでした;
今、インクルードしてみましたが、やはり2つ文字列を入力した時点でとまってしまいます。

Re:課題ができません;誰かアドバイスを!

#4

投稿記事 by » 18年前

まず、
規約と使い方
を読みましょう。
使っているのはGCCですか?BCCですか?

GCCなら知りません。

BCCなら

警告 W8065 test_ganmo.c 33: プロトタイプ宣言のない関数 'strlen' の呼び出し(関数str_plus )
警告 W8065 test_ganmo.c 34: プロトタイプ宣言のない関数 'strlen' の呼び出し(関数str_plus )
警告 W8060 test_ganmo.c 38: おそらく不正な代入(関数 str_plus )
警告 W8070 test_ganmo.c 53: 関数は値を返すべき(関数 main )

を解決してください。(行数は変わっています。)

この問題を解決すると…
E:\C++\2007-11-07>test_ganmo.exe
12
45
1/

E:\C++\2007-11-07>test_ganmo.exe
itirou
jirou
.(60/0

E:\C++\2007-11-07>test_ganmo.exe
jaja
jak
1830

という実行結果が出てきます。
したいことは、一体どの様なことか分からなかったので、したいことを教えてください。
とりあえず、プログラムはコンパイルしてみてください。
多分GCCでもエラーが出るのではないかと思うのですが…どうなんでしょうか???

がんも

Re:課題ができません;誰かアドバイスを!

#5

投稿記事 by がんも » 18年前

すみません。まず自分の環境なんですが、
プログラミングは習い始めてまだ6ヶ月くらいの初心者です。
BCCかGCCかということですが、正直なんのことかよくわかりません;すみません。
使っているコンパイラはcygwinです。


何がしたいかというのは、
最終は「きわめて大きな2 進数を10 進数に変換するプログラム」を作りたいんです。
「この場合,整数型変数を用いて処理しようとすれば桁あふれが生ずる.( int 型変数があつかうことのできる2 進数の上限は31 桁である.)
そこで,変換したい2 進数を文字配列におさめ,文字配列上の処理のみを行なって目的とする10 進数
に変換することを考える」という課題です。
今はその途中段階で、2つの文字列をたす関数を作ってるんです。
この説明でわかっていただけますか?;;


Re:課題ができません;誰かアドバイスを!

#7

投稿記事 by » 18年前

確認用を入れまくってますが…
//要変更箇所
n = a0 - '0' + a1 - '0' + a2 ;

if( n>(9*2) )
n = n - '0';
//ここまで

ここに注目してください。
かなり無理やりやってますが…
もっと良い方法があると思いますが、これ以上思いつきませんでした。

i == 0
の時はa2は存在しないのに、'0'を引いているので問題が生じている。
i >= 1
の時は問題が無い
else
の時はa1が存在しないので、これも i == 0 と同じ状態です。

これを解消するとOKだと思います。

この存在しない時のa1,a2を判別する式が分かれば確実なのが出来るのですが…

/*
123
12

最終回答:135
*/
と回答はなりました。
bcc32を使用しています。

フリオ

Re:課題ができません;誰かアドバイスを!

#8

投稿記事 by フリオ » 18年前

 
 gccだと #include <string.h> がなくてもエラーが出ませんね。

 とりあえず、気づいたことだけ、
> if(i = 0) char3plus(t1,t2,0,&k0,&t3); 
       ~                          ~
> else char3plus(t1,0,k1,&k0,&t3); 
                       ~

あと、これを修正しても、
999 1
000
の様に、最後の桁上がりが無視されることがあります。
 

miyaza

Re:課題ができません;誰かアドバイスを!

#9

投稿記事 by miyaza » 18年前

a2が存在しなくて'0'を引くのが問題であれば、
0ではなく'0'を引数として渡せばいいとおもいます。

フリオ

Re:課題ができません;誰かアドバイスを!

#10

投稿記事 by フリオ » 18年前

 
 いろいろな考え方があると思いますが、私なりに修正してみました。
#include <stdio.h>
#include <string.h> /* 追加 */

void str_rev(char s[/url], char t[/url])
{
	int i = strlen(s) - 1, n; /* 修正 */
	
	/*while(s != '\0') i ++;*/  /* 修正 */
	/*k = i;*/ /* 修正 */
	for(n = 0; n <= i; n ++){ /* 修正 */
	/*i --;*/ /* 修正 */
	t[n] = s; /* 修正 */
	}
}

void char3plus(char a0, char a1, char *b0, char *b1) /* 修正 */
{ 
	char n;
	
	n = a0 - '0' + a1 - '0' + *b0 - '0'; /* 修正 */
	*b0 = n / 10 + '0';
	*b1 = n % 10 + '0';
}

void str_plus(char s1[/url], char s2[/url], char s3[/url])
{ 
	char t1[100] = "\0", t2[100] = "\0", t3[100] = "\0", k0 = '0'; /* 修正 */
	int n1, n2, i;
	
	n1 = strlen(s1);
	n2 = strlen(s2);
	str_rev(s1, t1);
	str_rev(s2, t2);
	for(i = 0; i < n1; i ++){
		if(i == 0) char3plus(t1, t2, &k0, &t3); /* 修正 */
		else if(i >= 1 && n2 > i) char3plus(t1, t2, &k0, &t3); /* 修正 */
		else char3plus(t1, '0', &k0, &t3); /* 修正 */
		/*k1 = k0;*/ /* 修正 */
	}
	if(k0 != '0') t3[i] = k0; /* 追加 */
	str_rev(t3, s3);
}

int main(void)
{ 
	char s1[100], s2[100], s3[100] = "\0";
	
	scanf("%s %s", s1, s2);
	str_plus(s1, s2, s3);
	printf("%s\n", s3);
	return 0; /* 追加 */
}

 
 以下は、私が考えたものです。参考になれば。
void cha_plus(char c1, char c2, char *c3, int *r)
{
	*r += c1 - '0' + c2 - '0';
	*c3 = *r % 10 + '0';
	*r /= 10;
}

void str_plus(char *s1, char *s2, char *s3)
{
	char t1[100], t2[100], t3[100];
	int r, i, j;
	
	rev_str(s1, t1);
	rev_str(s2, t2);
	for(r = i = 0; t1[i] && t2[i]; i ++) cha_plus(t1[i], t2[i], &t3[i], &r);
	j = i;
	for( ;t1[i]; i ++) cha_plus(t1[i], '0', &t3[i], &r);
	for( ;t2[j]; j ++) cha_plus('0', t2[j], &t3[j], &r);
	i = i < j ? j : i;
	if(r) t3[i ++] = r + '0';
	t3[i] = '\0';
	rev_str(t3, s3);
}

がんも

Re:課題ができません;誰かアドバイスを!

#11

投稿記事 by がんも » 18年前

みなさんのおかげで、なんとかできました!ありがとうございます。
そしてたびたび申し訳ないですが、もうひとつアドバイスを!

http://www.comm.info.eng.osaka-cu.ac.jp ... /10_26.pdf
の問題の4問目までいきました。
2進数を10進数になおすプログラムを作ることができたのですが
次の課題ができません;;
2進数の書いてあるbinary.datファイルから読み込み
10進数に変換して、decimal.datに書き出すプログラムです。

コンパイルはできました。decimal.datの中を見てみると、かなり変な文字列になってしまいます;;
どなたかぜひ教えてください!


#include<stdio.h>
#include<string.h>
#define MAX 800

void str_rev(char s[/url], char t[/url])
{
int i = strlen(s) - 1, n;

for(n = 0; n <= i; n++) t[n] = s;

}


void char3plus(char a0, char a1,char a2, char *b0, char *b1)
{
char n;

n = a0 - '0' + a1 - '0' + a2 - '0';

*b0 = n/10 + '0';

*b1 = n%10 + '0';

}


void str_plus(char s1[/url], char s2[/url], char s3[/url])
{
char t1[100] = "\0", t2[100] = "\0", t3[100] = "\0", k0 = '0';
int n1, n2, i;

n1 = strlen(s1);

n2 = strlen(s2);

str_rev(s1,t1);

str_rev(s2,t2);

for(i = 0; i < n1; i++){

if(i == 0) char3plus(t1,t2,'0',&k0,&t3);
else if(i >= 1 && n2 > i) char3plus(t1,t2,k0,&k0,&t3);
else char3plus(t1,'0',k0,&k0,&t3);
if(k0 != '0') t3[i+1]=k0;
}

str_rev(t3,s3);


}


char *char_str(char c)
{
static char s[2];

s[0] = c; s[1] =0;

return s;
}


void bin_deci(char bin[/url], char deci[/url])
{
char s[1000000];
int i, n;

strcpy(s, char_str(bin[0]));

n = strlen(bin) - 1;

for(i = 0; i < n; i++)
{
str_plus(s,s,deci);str_plus(deci,char_str(bin[i+1]),s);

}

strcpy(deci,s);

}

int main(void)
{
FILE *fp1, *fp2;
char s[MAX], t[MAX];

fp1 = fopen("binary.dat","r");
fp2 = fopen("decimal.dat","w");

if(fp1 == NULL) { printf("Error!\n"); exit(1); }

while(fgets(s, MAX-1, fp1) != NULL){

bin_deci(s,t);

fputs(t,fp2);

}

}

Re:課題ができません;誰かアドバイスを!

#12

投稿記事 by » 18年前

・・・まず、利用規約をもう一度呼んでください。
fcloseしてください。
binary.datのファイル添付してください。

どこが悪いと思いますか?
どこで書き込んでいますか?

がんも

Re:課題ができません;誰かアドバイスを!

#13

投稿記事 by がんも » 18年前

何度も何度もマナー違反のようで、本当にすみません!!;;

main関数以外はちゃんと動くのを確認しましたので、main関数の中がおかしいとおもうのですが…
fgetsの使い方がおかしいのでしょうか・・・

どこで書き込んでるか、というのはファイルに書き込むってことですか?

フリオ

Re:課題ができません;誰かアドバイスを!

#14

投稿記事 by フリオ » 18年前

 
 "fgets"は、改行まで読み込み、"fputs"は、改行をつけません。

 それと、文字列の終端は、初期化に頼るのではなく、
それぞれの処理ごとに '\0' をつけるようにしたほうがいいと思います。
 

Re:課題ができません;誰かアドバイスを!

#15

投稿記事 by » 18年前

>マナー違反のようで…
マナー違反と言うか…<pre></pre>つけてないと見にくすぎて、、、ね?(ぇ

--追加
…このプログラムは一回一回違う…10進数に本当に出来ていますか?

--追加
このプログラムはうまく10進数にはなっていません。

--実行結果--
8169--'-58-,
1421254,(+(*135*)*
101554732994..'0),.8'*16-/-0721*
13209090981479772*0./+*,-)*680+3640+.
121682478924980663867*)-',-.0(0/*7773931+-+),(+490+,8.-1)(-.2(
--End--

これが改行無しで書き込まれています。
確認用にprintfなどを使っていれば、それを消さずにUPしてください。

Re:課題ができません;誰かアドバイスを!

#16

投稿記事 by » 18年前

2進数から10進数への変換
文字から数字に直行しています。
これを数字から文字に直せばOKかな…
課題の方法と違う気がするのですが…

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

int keisan(int set)
{
	printf("set:%d\n",set);
	if(set == 0)
		return 2;
	return 2*keisan(set-1);
}

void TwoToTen(char number[/url])
{
	int i, longer, ans=0,sum=0;
	
	longer = strlen(number)-1;
	printf("longer:%d\n",longer);
	
	for(i=0; i<=longer; i++){
		printf("\nnumber[%d] - '0':%d\n", i, number[longer-i]-'0');
		printf("-ans:%d\n",ans);
		if(i==0)
			ans = 1 * (number[longer-i]-'0');
		else
			ans = keisan(i-1) * (number[longer-i]-'0');
		printf("+ans:%d\n",ans);
		sum += ans;

	}
	printf("TwoToTen:sum : %d\n",sum);
		
}


int main ()
{
	char number[/url]={"110"};
	
	TwoToTen(number);
	
	return 0;
}

フリオ

Re:課題ができません;誰かアドバイスを!

#17

投稿記事 by フリオ » 18年前

 
 とりあえず、これで期待通りに動きます。
#include<stdio.h>
#include<string.h>
#include <stdlib.h> /* 追加 */

#define MAX 800

void str_rev(char s[/url], char t[/url])
{
	int i = strlen(s) - 1, n;
	
	for(n = 0; n <= i; n ++) t[n] = s;
	t[n] = '\0'; /* 追加 */
}

void char3plus(char a0, char a1,char a2, char *b0, char *b1)
{
	char n;
	
	n = a0 - '0' + a1 - '0' + a2 - '0';
	*b0 = n / 10 + '0';
	*b1 = n % 10 + '0';
}

void str_plus(char s1[/url], char s2[/url], char s3[/url])
{
	char t1[100] = "\0", t2[100] = "\0", t3[100] = "\0", k0 = '0';
	int n1, n2, i;
	
	n1 = strlen(s1);
	n2 = strlen(s2);
	str_rev(s1, t1);
	str_rev(s2, t2);
	for(i = 0; i < n1; i ++){
		if(i == 0) char3plus(t1, t2, '0', &k0, &t3);
		else if(i >= 1 && n2 > i) char3plus(t1, t2, k0, &k0, &t3);
		else char3plus(t1, '0', k0, &k0, &t3);
		if(k0 != '0') t3[i + 1] = k0;
	}
	str_rev(t3, s3);
}

char *char_str(char c)
{
	static char s[2];
	
	s[0] = c;
	s[1] = 0;
	return s;
}

void bin_deci(char bin[/url], char deci[/url])
{
	char s[1000000];
	int i, n;
	
	strcpy(s, char_str(bin[0]));
	n = strlen(bin) - 1;
	for(i = 0; i < n; i ++){
		str_plus(s, s, deci);
		str_plus(deci, char_str(bin[i+1]), s);
	}
	strcpy(deci, s);
}

int main(void)
{
	FILE *fp1, *fp2;
	char s[MAX], t[MAX];
	int l; /* 追加 */
	
	fp1 = fopen("binary.dat", "r");
	fp2 = fopen("decimal.dat", "w");
	if(fp1 == NULL || fp2 == NULL){ /* 修正 */
		printf("Error!\n");
		exit(1);
	}
	while(fgets(s, MAX-1, fp1) != NULL){
		if(s[l = strlen(s) - 1] == '\n') s[[/url] = '\0'; /* 追加 */
		bin_deci(s, t);
		fputs(t, fp2);
		fputc('\n', fp2); /* 追加 */
	}
	return 0; /* 追加 */
}

 
 ファイルに、もうちょっといじったのを置いておきます。
 

フリオ

Re:課題ができません;誰かアドバイスを!

#18

投稿記事 by フリオ » 18年前

 
 "fclose"を忘れてました。
 

がんも

Re:課題ができません;誰かアドバイスを!

#19

投稿記事 by がんも » 18年前

お礼が遅れました!
みなさんのおかげでなんとか理できて、課題をだすことができました!
ありがとうございます

閉鎖

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