大学の課題について困っています><

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

大学の課題について困っています><

#1

投稿記事 by akm0127 » 14年前

はじめまして。大学の講義でプログラミングをとっていて、課題が出たのですが、行き詰まってしまい相談に参りました。
データ数、品名、単価、数量を入力すると、単価×数量=金額を計算して表示するプログラムを作成しなければならないのですが、なかなかうまくいきません。
教科書を眺めてみたり、友人に相談したりして以下のようなものを作りました。

コード:

#include <stdio.h> 
int main(void)
{
int n, gokei;  
char hinmei[256];  
int tanka[256], suryo[256], kingaku[256];  
int i, count;  

n=0;
suryo=0; 
count=0; 

for(i = 0;i < 256;i++)
{ 
hinmei[i] = 0; 
tanka[i] = 0; 
suryo[i] = 0; 
kingaku[i] = 0; 
} 

printf("入力するデータ数を入力してください>");
scanf("%d", &n);  
count = n;

while(n != 0)
{ 
printf("品名を入力してください>"); 
scanf("%c", &hinmei); 
hinmei[i] = hinmei; 

printf("単価を入力してください>"); 
scanf("%d", &tanka); 
tanka[i] = tanka; 

printf("数量を入力してください>"); 
scanf("%d", &suryo); 
kingaku[i] = tanka[i] * suryo[i]; 

gokei = kingaku[i] + gokei; 

n--;
i++;
} 

i = 0;
printf("品名     単価     数量     金額\n\n"); 
printf("----------------------------------------------\n\n"); 

while(count != 0) 
{ 
printf("%d     ,%c     ,%d     ,%d", hinmei[i], tanka[i], suryo[i], kingaku[i]);
printf("\n\n"); 
count--; 
i++; 
} 

printf("----------------------------------------------\n\n"); 
printf("合計                   %d", gokei); 

return 0; 

}
エラーがいくつか起きてしまい、うまく動きません。
完成例としては

(n=3の場合)
入力するデータ数を入力してください>3
品名を入力してください>食パン
単価を入力してください>150
数量を入力してください>2
品名を入力してください>たまご
単価を入力してください>220
数量を入力してください>1
品名を入力してください>チーズ
単価を入力してください>380
数量を入力してください>1

品名          単価  数量  金額
------------------------------------------------
食パン         150    2   300
たまご         220    1   220
チーズ         380    1   380
------------------------------------------------
合計                    900

のような感じを望んでいます。
丸一日悩みましたが、限界を感じたので・・・
構造体は?配列は?もっと省略できるのではないか?などと考えておりました。
どなたか修正点、もしくはまったく違う考え方でもかまいません、良ければご教授願います。
(当方文系大学でプログラミングはド初心者ですので、甘口で評価していただけると助かります^^;)

アバター
bitter_fox
記事: 607
登録日時: 14年前
住所: 大阪府

Re: 大学の課題について困っています><

#2

投稿記事 by bitter_fox » 14年前

akm0127 さんが書きました: エラーがいくつか起きてしまい、うまく動きません。
エラーがいくつか発生したとのことですが、
フォーラムルールは読まれましたでしょうか??

フォーラムルールには、

「うまくいきません」という質問は大抵回答に困ります。
  3. どのようなエラーやトラブルで困っていて

この点をしっかりと明記して下さい。

コンパイルエラーの質問時は必ず最低限のエラーメッセージも書きましょう。

[hr]
「ゲーム作っているのですが、うまく作れません」
「コンパイルしたのですが、うまくコンパイルできません」
この手の質問はよく回答に困ります。
コンパイルエラーの質問の場合、エラーメッセージをコピペするのは最重要です。
とあります、これに則った質問をお願いします。
というわけで、どういったコンパイルエラーが発生するのでしょうか??

また、コードを見るとインデントが一切されてないのですが、自動インデント機能付きエディタや統合開発環境はご使用になられてないのでしょうか?
インデントがないのはバグの温床になります。
akm0127 さんが書きました:完成例としては...(略)
どなたか修正点、もしくはまったく違う考え方でもかまいません、良ければご教授願います。
了解しました。

akm0127

Re: 大学の課題について困っています><

#3

投稿記事 by akm0127 » 14年前

返信ありがとうございます。
無知なもので、何をどう説明すればいいのかも曖昧でした><
ご指摘ありがとうございます。
エラーメッセージですが、どう説明すればいいのかわからないので原文ままコピーさせてもらいます。
以下エラーメッセージ

1>c:\users\minato\documents\visual studio 2008\projects\2\2\2.cpp(14) : error C2440: '=' : 'int' から 'int [256]' に変換できません。
1> 配列型への変換はありませんが、参照またはポインタから配列への変換があります。
1>c:\users\minato\documents\visual studio 2008\projects\2\2\2.cpp(33) : error C2440: '=' : 'char [256]' から 'char' に変換できません。
1> この変換が可能なコンテキストはありません。
1>c:\users\minato\documents\visual studio 2008\projects\2\2\2.cpp(37) : error C2440: '=' : 'int [256]' から 'int' に変換できません。
1> この変換が可能なコンテキストはありません。


具体的には、初期化の suryo=0;の行
while文の中の hinmei = hinmei;
おなじく tanka = tanka;の行でエラーが出ているようです。 


あと、大変申し訳ありません・・・。
インデントやエディタ等はちんぷんかんぷんで(泣)
ちょっとなんとも答えることができなさそうです、ごめんなさい。
一応、現在このプログラムはvisual studio 2008で作成していて、課題提出も同環境での動作が確認されればOKとのことでした。

自分の無知さが浮き彫りになるような質問の仕方や回答で申し訳ありません。
引き続きよろしくお願いいたします。

アバター
h2so5
副管理人
記事: 2212
登録日時: 14年前
住所: 東京
連絡を取る:

Re: 大学の課題について困っています><

#4

投稿記事 by h2so5 » 14年前

確認しておきたいのですが、
hinmei[256], tanka[256], suryo[256], kingaku[256] の4つの配列は
それぞれ何のための配列として使っているつもりでしょうか?

追記:
例えば、
scanf("%c", &hinmei);
hinmei = hinmei;
の部分のソースはどのような処理を期待しているのでしょうか?

akm0127

Re: 大学の課題について困っています><

#5

投稿記事 by akm0127 » 14年前

>hinmei[256], tanka[256], suryo[256], kingaku[256] の4つの配列は
>それぞれ何のための配列として使っているつもりでしょうか?

>scanf("%c", &hinmei);
>hinmei = hinmei;
>の部分のソースはどのような処理を期待しているのでしょうか?

もうほんとに1から勉強しなおせって感じですが、正直苦し紛れで自分でもよくわかっていないんです。
教科書を真似ながらやっただけで、それぞれの役割もあまり理解できていない部分も多く・・・。
試行回数について、3回など具体的な数値が挙げられていればいいのですが、
それも入力された数字に依存されているので、正直お手上げ状態で><
明日が提出期限なので、焦ってここを利用させてもらっています。
質問に答えられず申し訳ありません。
よろしければ解答例と解説をいただければ助かります。

アバター
bitter_fox
記事: 607
登録日時: 14年前
住所: 大阪府

Re: 大学の課題について困っています><

#6

投稿記事 by bitter_fox » 14年前

akm0127 さんが書きました: 明日が提出期限なので、焦ってここを利用させてもらっています。
質問に答えられず申し訳ありません。
よろしければ解答例と解説をいただければ助かります。
フォーラムルールにより丸投げは禁止されています。
取りあえず、問題点と主な修正点を、、、

コード:


#include <stdio.h> 

int main(void)
{
	int n, gokei;  
	char hinmei[256]; // 文字列の場合だと、もう一次元が必要。
//	char hinmei[256][256] = {0}; // ここは入力されるので初期化不要
	int tanka[256], suryo[256], kingaku[256];
//	int tanka[256] = {0}, suryo[256] = {0}, kingaku[256] = {0}; // ここは入力されるので初期化自体が不要
	int i, count;  

	n=0;
	suryo=0; // suryoは配列なので、この代入は不正。
	count=0; 

	for(i = 0;i < 256;i++)	// ここは、省略可能な処理
							// int tanka[256] = {0};で代用可(ないしはmemset関数を使用)
							// また、後で入力されるのでそもそも初期化は不要
	{ 
		hinmei[i] = 0; 
		tanka[i] = 0; 
		suryo[i] = 0; 
		kingaku[i] = 0; 
	} // この時点でiの値は256になってる

	printf("入力するデータ数を入力してください>");
	scanf("%d", &n);
	count = n;

	// iの値が256のまま、アクセスしており配列外を参照している
	// (さらにそのあとインクリメントしてるのでどんどん配列外を参照することになってる)
	while(n != 0) // for (count = 0; count < n; count++)の方がスマート こうしたらcount = nは不要
	{ 
		printf("品名を入力してください>"); 
		scanf("%c", &hinmei); // ここは明らかにおかしい
		hinmei[i] = hinmei;   // これも、間違い。

		//scanf("%s", hinmei[count]); で正解 (ただし、項目数が256を超えた時に配列外を参照することになってしまう。)

		printf("単価を入力してください>"); 
		scanf("%d", &tanka); // 間違い
		tanka[i] = tanka;    // 同様

		//scanf("%d", &tanka[count]); で正解

		printf("数量を入力してください>"); 
		scanf("%d", &suryo);              // scanf("%d", &suryo[count]):
		kingaku[i] = tanka[i] * suryo[i]; // iをcountに変更

		gokei = kingaku[i] + gokei;       // gokeiが初期化されていない。

		n--; // 不要
		i++; // 不要
	} 

	i = 0;
	printf("品名     単価     数量     金額\n\n"); // 改行しすぎ
	printf("----------------------------------------------\n\n"); // 改行しすぎ

	while(count != 0) // for (count = 0; count < n; count++)の方がスマート
	{
		// iをcountに変更
		printf("%d     ,%c     ,%d     ,%d", hinmei[i], tanka[i], suryo[i], kingaku[i]); // 一個目は%s二つ目は%d(桁数が変動すると表示が乱れる)
		printf("\n\n"); // 改行しすぎ、上のprintfに入れれる。
		count--;        // 不要
		i++;            // 不要
	} 

	printf("----------------------------------------------\n\n"); 
	printf("合計                   %d", gokei); // ここも、合計の値の桁が増えると表示が乱れるので美しくない。

	return 0; 
}

// 確かに構造体にした方がスマートになるますね。
// 無駄な初期化が多くて、ほんとに初期化が必要な変数への初期化ができてない。(ケアレスミスかと思いますが・・・)
// 入力の受け方が質問者さんの中でまだ曖昧のように感じます。
// ループにwhileを多用していますが、用途によっては、forの方がスマートにできる。
// (もちろん用途によってはwhileの方がスマートになります。)

akm0127

Re: 大学の課題について困っています><

#7

投稿記事 by akm0127 » 14年前

ご指導ありがとうございます。
悩んだ末・・・でしたので丸投げのつもりは無かったのですが、申し訳ありません。

コード:

#include <stdio.h> 
 
int main(void)
{
	int n, gokei;  
    char hinmei[256][256] = {0};
    int tanka[256] = {0}, suryo[256] = {0}, kingaku[256] = {0};
    int i, count;  
 
    n=0;
    count=0;
	gokei=0;

   i = 0;
    printf("入力するデータ数を入力してください>");
    scanf("%d", &n);
    count = n;
 
     for (count = 0; count < n; count++)
    { 
        printf("品名を入力してください>"); 
        scanf("%s", hinmei[count]);
 
        printf("単価を入力してください>"); 
        scanf("%d", &tanka[count]);
 
        printf("数量を入力してください>"); 
        scanf("%d", &suryo[count]);
        kingaku[count] = tanka[count] * suryo[count];
 
        gokei = kingaku[i] + gokei;
 

    } 
 
    i = 0;
    printf("品名     単価     数量     金額\n");
    printf("----------------------------------------------\n"); 
    for (count = 0; count < n; count++)
    {
        printf("%s     ,%d     ,%d     ,%d", hinmei[count], tanka[count], suryo[count], kingaku[count]);
        printf("\n");
    } 
 
    printf("----------------------------------------------\n\n"); 
    printf("合計                   %d", gokei);
 
    return 0; 
}
 
教わった通りに、自分でわかる範囲で書き換えてみました。
ただ、合計の値がうまく計算できず、また、ご指摘の通り桁数が変わったときにレイアウトが崩れてしまいます。
ヒントをいただければ助かります><

アバター
bitter_fox
記事: 607
登録日時: 14年前
住所: 大阪府

Re: 大学の課題について困っています><

#8

投稿記事 by bitter_fox » 14年前

akm0127 さんが書きました: 教わった通りに、自分でわかる範囲で書き換えてみました。
ただ、合計の値がうまく計算できず
変数iは不要ですし、
count = nも不要です。
gokeiへの代入式の添え字が変更されていません。
見た感じ、コメントを追っただけの様に見えますが、
次は、変更したコードの意味とそれが与える影響を一つ一つ見て行ってみてください。
akm0127 さんが書きました: ご指摘の通り桁数が変わったときにレイアウトが崩れてしまいます。
ヒントをいただければ助かります><
では、ヒントとして以下のコードはどうでしょうか??

コード:


#include <stdio.h>

void main()
{
	char str[11];

	scanf("%10s", str);
	printf("Inputed String Is\n"
		 "123456789A\n"
		 "%-10s\n", str);
}
ポイントとしては、printfの%-10sというところでしょうか・・・
[hr][編集]
printfのフォーマット指定を左寄せに変更しました。
最後に編集したユーザー bitter_fox on 2011年1月13日(木) 14:17 [ 編集 2 回目 ]

akm0127

Re: 大学の課題について困っています><

#9

投稿記事 by akm0127 » 14年前

ヒントありがとうございます。
皆さんがおっしゃっていたことを参考に、もう一度1からなるべくシンプルに組みなおしてみました。
構造体は課題提出の範囲外でしたので、結局今回は使わないままでした。

コード:

#include <stdio.h> 
 
int main(void)
{
	int n, gokei;  
    char hinmei[256][256];
    int tanka[256], suryo[256], kingaku[256];
    int i;  

    printf("入力するデータ数を入力してください>");
    scanf("%d", &n);
    i = n;
 
     for (i = 0; i < n; i++)
    { 
        printf("品名を入力してください>"); 
        scanf("%s", hinmei[i]);
 
        printf("単価を入力してください>"); 
        scanf("%d", &tanka[i]);
 
        printf("数量を入力してください>"); 
        scanf("%d", &suryo[i]);
        kingaku[i] = tanka[i] * suryo[i];
    } 
 
    i = 0;
    printf("品名          単価      数量      金額\n");
    printf("------------------------------------------------------------\n"); 
    for (i = 0; i < n; i++)
    {
        printf("%-16s        %-10d        %-10d\n", hinmei[i], tanka[i], suryo[i]);
		printf("%60d\n",kingaku[i]);
    } 
 
    printf("-----------------------------------------------------------\n"); 

   gokei=0;
   for(i=0; i<n; i++)
   { 
	   gokei=gokei+kingaku[i];
   }
   printf("合計%56d\n",gokei);
 
    return 0; 
}
 
一応希望どおりに動くようになりましたが、レイアウトの合わせについては多少強引に調節したと思っています。
ひとつ前で教えてくださったコードは私には少し複雑で、右揃え・左揃えについてのみ参考にさせてもらいました。
できるだけ単純でシンプルなソースで課題を提出したいと思っています。
最初に言っていたことと大きく変わってしまいましたが、改善点などあれば引き続き教えていただきたいです。

アバター
bitter_fox
記事: 607
登録日時: 14年前
住所: 大阪府

Re: 大学の課題について困っています><

#10

投稿記事 by bitter_fox » 14年前

akm0127 さんが書きました: 一応希望どおりに動くようになりましたが、レイアウトの合わせについては多少強引に調節したと思っています。
まだ、ちょっとずれてるので、そこも修正しておきましょう。(数量とボーダー)
(金額が次行に行ってるのが気になりますが・・・)
akm0127 さんが書きました: できるだけ単純でシンプルなソースで課題を提出したいと思っています。
最初に言っていたことと大きく変わってしまいましたが、改善点などあれば引き続き教えていただきたいです。
合計の計算の位置ですが、僕的には、入力と同時に加算していく方が好きですね。
それから、習ってるかどうかわかりませんが、合計への代入は+=演算子を使いたいですね・・・

あと、12行目と27行目は不要ですね。

[hr][追記]
せっかく出力フォーマットを%16sといったようにしてるのですから、そのあとのスペースが無駄に感じてしまいます。
その分も出力幅指定に入れてしまった方がきれいでしょう。

akm0127

Re: 大学の課題について困っています><

#11

投稿記事 by akm0127 » 14年前

ありがとうございます。
だいぶすっきりしてきました。
あと、ここにきて初歩的な質問で申し訳ないんですが、

コード:

    int n, gokei;  
    char hinmei[256][256];
    int tanka[256], suryo[256], kingaku[256];
    int i;
の部分、"[256]"を打ち込むことはどのような役割を持っているのでしょうか?
256という数字を使う意味が分かりません。
他の数では駄目なのか、使わない方法はあるのか、説明していただけると幸いです。

アバター
bitter_fox
記事: 607
登録日時: 14年前
住所: 大阪府

Re: 大学の課題について困っています><

#12

投稿記事 by bitter_fox » 14年前

akm0127 さんが書きました:

コード:

    int n, gokei;  
    char hinmei[256][256];
    int tanka[256], suryo[256], kingaku[256];
    int i;
の部分、"[256]"を打ち込むことはどのような役割を持っているのでしょうか?
256という数字を使う意味が分かりません。
他の数では駄目なのか、使わない方法はあるのか、説明していただけると幸いです。
256という数字の意味ですが、この値は実は2の8乗になっていまして、こういった値がプログラマは好きなんですよね。。。w(他にも512, 1024何かが主に好まれますね)
(むしろこの値の方がキリがいいとさえ言い出しますwww)

他の数字でも問題ないですよ、ただ十分な大きさでないとバッファオーバーフローが発生してしまいますので、注意してください。

使わない方法とのことですが、ポインタとして用意して動的確保するなどといった方法がありますが、まだ習ってないのであったらこれから習うことになるでしょうね・・・
(構造体だとリスト構造と言ったものもありますし、他にもいろんな方法があります。)

[hr]今、ソースを見直したら256という値が点在していてキレイではないですね。(今のやつだと、どこか一つ変えたら他もいっぱい変えることになってしまいますよね?もし、変え忘れがあると・・・)
というわけで、

コード:

#define MAX 256
という書き方(マクロ置換)は習ってますでしょうか??
すでに、習っているのであればこうしておきましょう。

後オーバーフローが発生してしまうのはよろしくないので、

コード:

	scanf("%255s", str); // これは文字列のみ (256-1の値になってるのは文字列の最後に'\0'が付与されるためです)
//	scanf("%*s", MAX-1, str); 上の定数を使った場合はこのように指定します。
	while (getchar() != '\n'); // もしも制限よりも多くの文字列が入力されたら余りがバッファに残るので、その分を読み取る。
といった風にして、
さらに、入力してもらったn(入力項目数)の値も調べて256以下でなかったらエラーを出力するとか、nの値を最大の256に変更するなどしておけば安全でしょう。

maru
記事: 150
登録日時: 14年前

Re: 大学の課題について困っています><

#13

投稿記事 by maru » 14年前

akm0127 さんが書きました:ありがとうございます。
だいぶすっきりしてきました。
あと、ここにきて初歩的な質問で申し訳ないんですが、

コード:

    int n, gokei;  
    char hinmei[256][256];
    int tanka[256], suryo[256], kingaku[256];
    int i;
の部分、"[256]"を打ち込むことはどのような役割を持っているのでしょうか?
256という数字を使う意味が分かりません。
他の数では駄目なのか、使わない方法はあるのか、説明していただけると幸いです。
256という数値の意味は bitter_fox さんが説明しておられる通りです。
他の数値では駄目か?という問いはあなた(又は出題者)に対して返さなければなりません。
この数値が課題のデータ数の最大値であることは認識しておられるでしょうか?
課題では入力するデータ数の最大値を指示していないので、このプログラムでは257個以上の
データを保持することができませんし、入力時にその上限をチェックしていません。
もし課題にデータ数は最大でもx個という指示があれば数値は256ではなくその値を使用すれば
いいでしょう。(ただしその数が非常に大きい場合は数値を変えるだけではNGです。)
課題に最大数の指示がなければ、「最大数をxにしました。」(xは256)と但し書きをつけれ
ばよいでしょう。実際にxはいくつでもかまわないでしょう。

なお、hinmei[256][256];の後ろの256は品名の文字列を格納する為の領域サイズですので、
この数値は品名の最大文字列長+1あれば十分です。今は256なので255文字までのの長さの
品名を扱うことが出来ます。
ただし文字列長はchar単位なので日本語を使う場合、そのエンコードで文字列長さが変わる
ので注意が必要です。普通は日本語1文字はchar2文字分の領域を必要とします。

maru
記事: 150
登録日時: 14年前

Re: 大学の課題について困っています><

#14

投稿記事 by maru » 14年前

ついでに言っておきますが
char hinmei[256][256];
には256が二つありますが、意味が異なっているので
#define MAX 256
で両方を置き換えてはいけません。
それぞれ別々のマクロを与えなければなりません。

さらに言えばC++ではマクロは余り推奨されていません。
マクロが様々な副作用を引き起こすからです(その副作用は省略)。

C++では定数は

コード:

const int max_number = 256;             //データの最大数
const int max_length_of_name = 255; //文字列最大長
char hinmei[max_number][max_length_of_name+1];
のように定義して使います。
もちろん max_length_of_name を256にして hinmei の [max_length_of_name+1] を [max_length_of_name] にしてもかまいません。

閉鎖

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