ページ 11

入力値の和を求めるには

Posted: 2006年12月07日(木) 20:09
by たくみ
こんばんわ 「配列に文字を入力し、その配列全て足し合わせ、文字と和をファイルに保存する」 という課題をいただいたのですが、どうしていいかまったくわからず悩んでいます 教えてくださいおねがいします

Re:配列

Posted: 2006年12月07日(木) 20:35
by 管理人
たくみさんこんばんは。
管理人です。


>配列に文字を入力し、その配列全て足し合わせ、文字と和をファイルに保存する

数値を入力するんじゃなくて文字なんですか?
それとも数値を文字として読み込んで、数字に変換し、たしあわせて、さらに文字として出力するということですか?

どこで躓いていますか?

Re:配列

Posted: 2006年12月07日(木) 23:47
by 管理人
キーボードから文字を入力するのに、初心者のうちによく使われる関数は
scanf
getchar
だと思いますが亜、
「配列に文字を入力し」
という言葉からしても
scanf("%d",&a);
とするのはダメみたいですね。
getchar関数で1文字ずつ読み取って配列にいれていく方法が思いつかれますけれども、

たとえばgetchar関数を使用して
1234
と入力した際に
st[0]=1
st[1]=2
st[2]=3
st[3]=4
st[4]=\0
と格納し、atoi関数という文字列をint型関数に変換する関数を使って
整数型にし、そこから和を求める方法です。

出力は%dを使って整数型として出力するほうが一般的だと思いますが、文字列にまた直して
ファイルに出力したほうがいいんですか?

このプログラムは主に3つに分かれると思います。

・文字入力
・和を求める
・ファイル出力

このどの辺でつまづいていらっしゃいますか?

Re:配列

Posted: 2006年12月08日(金) 02:30
by たくみ
正直にいえばすべてでつまずいてしまっています ごめんなさい。
先生におききしたところ、数値を文字として読み込んで、たしあわせて、文字とそのたしあわせた値2つを出力して保存するということらしいです

Re:配列

Posted: 2006年12月08日(金) 02:51
by 管理人
まず、入力するというプログラムを考えましょう。

scanfという関数を使えば、キーボードからの入力が格納できます。
http://www5c.biglobe.ne.jp/~ecb/c/c00.html
こちらのサイトでscanfについて勉強してください。

文字列
char st[100];
と宣言すれば、99個最大で文字が格納できます。
というのも文字列というのは最後に文字列の最後である終端記号\0が必要だからです。
実際に数字が格納できるのは準備した要素数-1になるわけです。

ところで、関数の書き方は

scanf("%s",st);

です。
するとこの関数に差し掛かったとき、stに入力文字列が格納されます。
実際に表示されたかどうか確認するのはprintfでできますから

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

で表現できますね。

では、これらを使って、まず

・文字列宣言
・キーボードから1文読み取り
・入力結果表示

を行うプログラムを自分で作ってみてください。
出来たら投稿してください。

Re:配列

Posted: 2006年12月08日(金) 22:06
by たくみ
すみませんサイトをみたり教科書や図書館でしらべても、わかりませんでした。授業についていくのがやっとで、落ちこぼれの自分にはこの課題はどうしていいか皆目検討がつきません

Re:配列

Posted: 2006年12月08日(金) 22:46
by 管理人
C言語を書き始めるときは

#include <stdio.h>

と書きます。
これは入門のうちは「C言語のはじまり」という意味として覚えておけばいいでしょう。

プログラムにはすべてメイン関数というものが必要です。

void main(){

と書き始めます。
このメイン関数の中にすべての処理をかいていきます。

処理がおわれば

}

で閉じます。

これで、わかりますね?
自分の思うプログラムが出来るかと思いますが、どうでしょうか。
ちょっと自分の力でやってみてください。

Re:配列

Posted: 2006年12月09日(土) 03:49
by たくみ
そこまで無知なわけではなく、文字列を関数にわたすような

#include<stdio.h>

void strout(char ss{[/url]);

int main (void)
{
char st[/url]="ABCDEF"

strout(st);
strout("ABab12");

return0;
}
というようなものなら簡単にできるのですが、この問題は特別課題らしく調べられるものすべてを使ってよい
というかんじで学校の先生もあまり教えてくれず悩んでいるのが現状です

Re:配列

Posted: 2006年12月09日(土) 04:26
by Justy
 結局何をするプログラムを作りたいのかよくわからないのですが、推測すると

1 数値を入力させ、文字列として受け取る
2 文字列を数値化し、整数の配列に入れる
3 1と2を複数回繰り返し、配列を埋める(回数不明)
4 配列の中身の全要素を全て足す
5 ファイルに配列内の数値の羅列と、4の結果を書き出す

 か若しくは

1 charの配列に文字列を入力させる。
2 その配列の各 char値を加算する
3 1の文字列と2の結果をファイルに出力する

 のどちらかかな、と思いますが・・・。

(と、書いてる途中で後者の可能性が高そうな気がしてきました)

Re:配列

Posted: 2006年12月09日(土) 05:32
by 管理人
結局何がやりたいのかよくわかりませんし、
少しずつ解説していくと、全て解らないし検討もつかないといわれ、1から解説するとそこまで無知じゃないと
言われましても困ります・・。

>調べられるものすべてを使ってよいというかんじ

どういう感じかよくわかりませんが、標準関数や特定のライブラリ関数の使用制限がないということでしょうか。


・文字入力

・文字>数値変換

・和を求める

・ファイル出力

という処理ではだめなんですか?

それとも文字コードの質問なんですか?

Re:配列

Posted: 2006年12月09日(土) 08:58
by バグ
一通り読んでみたのですが、質問者の意図が分かりませんね…これでは答えようがないのでは?(^_^;)

Re:配列

Posted: 2006年12月10日(日) 03:20
by たくみ
今日先生にメールでしつこく聞いたところ今の自分たちのクラスのレベルでは解けないもんだいで、どのように考え答えを見つけ出してくるかがみたかったようです Justyさんの

1 charの配列に文字列を入力させる。
2 その配列の各 char値を加算する
3 1の文字列と2の結果をファイルに出力する

という考えで正解みたいでした。

Re:配列

Posted: 2006年12月10日(日) 03:27
by 管理人
>どのように考え答えを見つけ出してくるかがみたかったようです

難しい問題をどこまで解いてくるかみるというのならわかりますが、
よくわからないことする先生ですね・・。

>その配列の各 char値を加算する

つまり、文字コードの合計をだしたいわけでしょうか。

出力は
char型で、文字を出力
int型で文字コードの合計値を出力
でいいんでしょうか?

Re:配列

Posted: 2006年12月10日(日) 03:39
by 管理人
入力した文字コードの合計を求めるプログラムです。
#include <stdio.h>

int main(){
	int x[100],i=0,j,sum=0;
	while((x=getchar())!='\n' && i<100)
		i++;
	for(j=0;j<i;j++)
		sum+=x[j];
	return 0;
}


単純に配列の中身をたしているだけです。

Re:配列

Posted: 2006年12月10日(日) 18:22
by たくみ
わがままばかりいってしまいごまんなさい。 
管理人さんにしめしていただいた部分にあらたにつけたす感じで考えてゆけばいいんですよね

わかりません

Posted: 2006年12月11日(月) 01:13
by たくみ
管理人さんに示していただいたものを自分なりに本を見たり友達と相談しながらどう手を加えればよいのかいろいろ試してみましたが、思いどうりのものができません。 やはりむりなのでしょうか・・・・・ だれか助けてください

Re:わかりません

Posted: 2006年12月11日(月) 01:49
by ま~く
初めて質問の回答をします♪

いままでの流れを呼んでいて思ったのですが、たくみさんの質問
>「配列に文字を入力し、その配列全て足し合わせ、文字と和をファイルに保存する」
がそのままの課題の内容だとすると仕様が不明確ですよね。
(授業の流れ(この課題の出される授業の前回や前々回の授業)からある程度絞れるかもしれませんが・・・)

こんな課題が出されるか分からないけど、「仕様を詰める」と言うのが答えだったりして^^;

あ~でも
>1 charの配列に文字列を入力させる。
>2 その配列の各 char値を加算する
>3 1の文字列と2の結果をファイルに出力する

が正解と言ってるしなぁ~

Re:わかりません

Posted: 2006年12月11日(月) 01:49
by Justy
 実際問題、後は管理人さんのコードにファイルに保存する機能をつけるだけで完成すると思うのですが、具体的にどこで詰まっているのでしょうか。

いろいろ試してみましたが
 いろいろ試してみてどうなったのでしょうか。
 その最終版というか、たくみさんなりに正解に近いと思うコードを見せてください。

Re:わかりません

Posted: 2006年12月11日(月) 02:05
by たくみ
justy さんへ 保存する機能とは単にprintfをつけくわえる感じでよろしいのでしょうか

Re:わかりません

Posted: 2006年12月11日(月) 02:15
by Justy
単にprintfをつけくわえる感じで
 いえ、コンソール上のテキストへの出力ならそれでいいのですが、ファイルを対象にしているので fopen~fprintf/fputsなど~fcloseの一連のファイル操作処理を付け加える感じになります。

Re:わかりません

Posted: 2006年12月11日(月) 03:05
by たくみ
今まで単にprintfとかいていたのですが、それが間違いであったのかもしれません。fprintf(" "); というようなものをどのあたりに加えれば大丈夫なのでしょうか

Re:わかりません

Posted: 2006年12月11日(月) 03:18
by Justy
どのあたりに加えれば大丈夫なのでしょうか
 最後のあたりです。

Re:わかりません

Posted: 2006年12月11日(月) 08:30
by mas
fopen, fprintf等を検索してみましたか?
ファイル入出力に関しては数多くのサンプルが見つかるはずなので、
それを見たり、試しに実行してみると理解しやすいと思います。
もし解からないことがあるなら、どこが解からないかをはっきりさせてから、ここに質問すればよいでしょう。

Re:わかりません

Posted: 2006年12月12日(火) 23:46
by たくみ(ダメ人間)
fopen, fprintf両方ともまだ学校でならっていないものでした。検索してみて ファイルのオープン→ファイルの読み書き→ファイルのクローズという感じでつながっていくということを勉強させていただきました。fopenの式として、fopen(char filename,char openmode)とかくみたいでした。 fcloseというものもあわせてのっていましたが、
#include <stdio.h>

int main(){
int x[100],i=0,j,sum=0;
while((x=getchar())!='\n' && i<100)
i++;
for(j=0;j<i;j++)
sum+=x[j];
return 0;
}

このプログラムにもfopenとfclose両方いるのでしょうか

Re:わかりません

Posted: 2006年12月13日(水) 00:11
by 管理人
ファイル操作をしていないので、fopenはいりません。
ファイルを開いていないのならfcloseは必要ありません。

上記のプログラムはファイルからデータを取ってくる処理をしていません。

getcharでキーボードからの1文字ずつをとってくる処理になっています。

文字コードの合計を出したらそのまま終わっています。

Re:わかりません

Posted: 2006年12月13日(水) 00:25
by たくみ(ダメ人間)
他の方々から「後は保存する部品を組み込むだけだよ」というアドバイスと「fopenを使ってみたら」というアドバイスを受けたのですが、fopenは他の場所にtxtファイルがある時に呼んでくるのに使うとものっていました。 管理人さんに作っていただいたものはポインタというものなのでしょうか

Re:わかりません

Posted: 2006年12月13日(水) 01:06
by GPGA
[color=00B0FF]#include[/color] <stdio.h>
[color=00B0FF]#include[/color] <stdlib.h>

[color=00B0FF]int[/color] main()
{
    FILE* fp = NULL;
    [color=00B0FF]int[/color] num = 10;

    fp = fopen("test.txt", "w");
    [color=00B0FF]if[/color] (fp == NULL) {
        printf("ファイル書き込みエラー\n");
        exit(1);
    }
    fprintf(fp, "今日は%d才の誕生日だよ\n", num);
    fclose(fp);
        
    [color=00B0FF]return[/color] EXIT_SUCCESS;
}
 
上記のプログラムは、テキストファイルを作成しそこに文字列を書き込むサンプルプログラムです。

順番に解説します。
FILE* fp = NULL;
 
ファイルを扱う場合は、ファイルポインタを宣言します。
ファイルポインタ一つに付き、一ファイルを扱うと考えてください。
fp = fopen("test.txt", "w");
 
上記はファイルを開くプログラムです。
fopenの第一引数には対象になるファイルのパスを指定します。
第二引数には対象のファイルの扱いを指定します。
"w" はテキストファイルを新規に書き込むという意味です。
これは、test.txtが存在しなければ、新規に作成し
存在していれば、中身を全て消して新しく作るという意味です。

fopen関数は失敗するとNULLを返します。
したがって、fopenの後fpをチェックし、NULLであればエラー表示を行ってプログラムを終了します。
fprintf(fp, "今日は%d才の誕生日だよ\n", num);
 
fprintfは対象のファイルに文字列を書き込みます。
第一引数が対象となるファイルポインタとなり、第二引数以降は
printfと同じ扱いです。
fclose(fp);
 
使い終わったファイルは閉じましょう。

以上となります。
何かわからないところはありますでしょうか?

Re:わかりません

Posted: 2006年12月13日(水) 01:25
by たくみ(ダメ人間)
丁寧な解説ありがとうございます
今回の配列に文字を入力し、その配列全て足し合わせ、文字と和をファイルに保存する
1 charの配列に文字列を入力させる。
2 その配列の各 char値を加算する
3 1の文字列と2の結果をファイルに出力する

というもんだいではGPGAさんが解説してくださったtxtの部分を置き換える感じで管理人さんのプログラムに当てはめて考えていく感じでしょうか

Re:わかりません

Posted: 2006年12月13日(水) 01:59
by GPGA
> GPGAさんが解説してくださったtxtの部分を置き換える感じで管理人さんのプログラムに当てはめて考えていく感じでしょうか
今回の場合に関しては、そう考えてもらってかまいません。

Re:わかりません

Posted: 2006年12月13日(水) 02:07
by たくみ(ダメ人間)
わかりました 提出期限が今日の朝9時までなので徹夜でがんばってみます。 無理だったときはすいません

Re:わかりません

Posted: 2006年12月13日(水) 03:27
by 管理人
おぉ、ま~くさん、回答お初ありがとうございます♪

たくみさん、もうそのまんま答えが皆さんの回答に載ってます。
ちょこっとだけ付け足したらいいだけで。

明日が提出締め切りということで、もっとほとんど答え状態のものをお教えしますから、
是非完成させてください(というか付け足すだけです)

まず、文字コードを数えるだけならint型でも出来ますが、
xの宣言はここはchar型でやっておきましょう。

宣言は全部でこうです。
FILE* fp = NULL;
	int i=0,j,sum=0;
	char x[100];
文字列というものは最後に終端記号を入れる必要があります。
これは最後に%sで文字列を一括出力するためです。
x[?]='\0';
?の部分はどこになるか考えてみてください。

fprintfで使う表現指示文字は

・int型は%d
・char型文字列は%s

でしたね。もうここまで聞けば出来たでしょう。

なお、カウントの仕方は
for(j=0;j<i;j++)
		sum+=(int)x[j];
このようにするのが理想的☆

がんばってください!

Re:わかりません

Posted: 2006年12月13日(水) 13:32
by たくみ(ダメ人間)
今朝先生に提出してきました、今回は課題の文章もわかりずらかったため出した先生も少し後悔していました。あっているかどうかわかりませんが、こんな感じになりました

#include <stdio.h>

int main(){
     FILE* fp = NULL;
int i=0,j,sum=0;
int x[100],i=0,j,sum=0;
     char x[100];
while((x=getchar())!='\n' && i<100)
i++;
for(j=0;j<i;j++)
sum+=(int)x[j];
return 0;
}
自分では間違っているかどうか判断できないので
正解のプログラムを教えていただけませんでしょうか

Re:わかりません

Posted: 2006年12月13日(水) 14:01
by GPGA
[color=00B0FF]#include[/color] <stdio.h> 
[color=00B0FF]#include[/color] <stdlib.h>

[color=00B0FF]int[/color] main(){ 
    FILE* fp = NULL; 
    [color=00B0FF]int[/color] i = 0, j, sum = 0;
    [color=00B0FF]char[/color] x[100];

    // キーボードからの文字列を取得する 
    [color=00B0FF]while[/color] ((x = getchar()) != '\n' && i < 100) {
        i++;
    }
    x = '\0';    // 文字列の終端コードを代入

    // 文字コードの値を足す
    [color=00B0FF]for[/color] (j = 0; j < i; j++) {
        sum += ([color=00B0FF]int[/color])x[j];
    }

    // ファイルを開く
    fp = fopen("out.txt", "w");
    [color=00B0FF]if[/color] (fp == NULL) {
        printf("ファイル作成エラー\n");
        exit(1);
    }

    // out.txtに書き込む
    fprintf(fp, "配列の文字:%s\n", x);
    fprintf(fp, "char値の合計:%d\n", sum);

    // ファイルを閉じる
    fclose(fp);

    [color=00B0FF]return[/color] 0; 
}
 
模範解答です。
一行一行のプログラムが何を行っているのかを考え
わからない所があれば質問してください。

Re:わかりません

Posted: 2006年12月13日(水) 16:00
by 管理人
たくみさん、失礼ですが、自分の事をダメ人間と書く前に、自分で努力した姿勢が感じられません。

皆さんがあれだけわかりやすく答え同様の回答をしてくださっているにもかかわらず、
最後のプログラムにはファイル操作にかかわる処理が一つもありませんし、投稿されたソースは全角文字が含まれているので、コンパイルされたソースではないでしょう。

昨日からプログラムを勉強し始めた  という事ではないですよね。
そこまで無知ではありませんという投稿のプログラムを見ても、少し考えたら理解できるレベルのはずです。

GPGAさんが、ファイル処理のソースはどうかくか、説明も詳しく書いてくださっています。
たくみさんは、それを読みましたか?

自分でも「fopen」「fclose」などと検索してみたり、本で読んで勉強してみたりしましたか?

普段であれば、最後にまだ解決されてない方には模範ソースと並べて詳しく説明を書くところですが、
すでに全て説明はされているので、もう説明は書くことがありません。

たくみさんも、きっと興味があって情報系を専攻されているんでしょう。
その授業料や貴重な時間を無駄にしないように、しっかり頑張ってください。

嫌味で言っているのだと捉えられてはそれまでですが、もう少ししっかり気合をいれて頑張っていただきたくて言いました。
努力してぶつかった壁はみんなで一生懸命あなたを支えて乗り越えさせてくれるはずです。
頑張ってください。