質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

4回答

6334閲覧

C言語 ファイルを読み込んで逆順にして別のファイルに書き出す

keeen

総合スコア15

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2020/08/08 06:40

イメージ説明
ファイルを読み込むところまでは書けたのですが、その後別のファイルに逆順で書き出す、という部分に詰まっています。どのようにすれば良いのでしょうか?

C

1#include <stdio.h> 2int main(void){ 3 FILE *fp,*sf; 4 char name[20]; 5 double height, weight; 6 7 fp = fopen("score.txt","r"); 8 9 sf = fopen("score_r.txt","w"); 10 if(sf == NULL){ 11 printf("ファイルオープンエラー\n"); 12 return -1; 13 } 14 15 while(fscanf(fp,"%s %lf %lf",name,&height,&weight) == 3) 16 { 17 fprintf(fp,"%s %lf %lf",name,height,weight); 18 } 19 20 fclose(fp); 21 fclose(sf); 22return 0; 23}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

SHOMI

2020/08/08 07:13 編集

https://teratail.com/questions/277315 の質問でPUSH/POPが理解できたならname,height,weightをメンバに持たせて 読み取ったものをすべてPUSHし、POPで逆順に取得しながらfprintfすればいい。 それを前提として出題されているのでは?
dodox86

2020/08/08 07:35

前の質問に比べたら考えた跡が感じられませんね。低評価は私がしたものではありませんが、その辺りの丸投げ感がそのように評価されたのだと思います。
cateye

2020/08/08 08:01

行をまるごとひっくり返す“だけ”なのに、fscanf()やfprintf()が必要なのでしょうか?
Zuishin

2020/08/08 08:03

> ファイルを読み込むところまでは書けたのですが、 いやこれ見本でしょう。height とか weight とか関係ないもの入ってるし。
episteme

2020/08/08 08:14

> fscanf()やfprintf()が必要なのでしょうか? 問題が「名前 身長 体重 を"それぞれ"読み取る」とあるからには。 一行まるっと 読み/書き すればいいなら fgets/fputs で十分ですけどねー
SHOMI

2020/08/08 08:42 編集

一行まるごと読み書きすればいいだけですが、問題文に書いてある以上はfscanf/fprintfでやらないと0点or再提出でしょうね…
keeen

2020/08/08 13:36

焦ってしまってあまり考えずに質問してしまいました。 PUSH/POPの理解が前提となってるのかもしれません。もう少しゆっくり考えてみようと思います。
kazuma-s

2020/08/10 10:51

> ファイルを読み込むところまでは書けたのですが とありますが、それが正しく動いたことはどうやって確認しましたか? > その後別のファイルに逆順で書き出す、という部分に詰まっています。 逆順ではなく、正順に書き出すことはできますか? できたら、質問を編集してそのコードを追記してください。
guest

回答4

0

ベストアンサー

多分、再帰呼出しは習っていないだろうから、こんなコードはダメでしょうが、
とりあえずは動くでしょう。

C

1#include <stdio.h> 2 3void proc(FILE *fp, FILE *sf) 4{ 5 char name[21]; 6 double height, weight; 7 if (fscanf(fp, "%20s%lf%lf", name, &height, &weight) == 3) { 8 proc(fp, sf); 9 fprintf(sf, "%s %.1f %.1f\n", name, height, weight); 10 } 11} 12 13int main(void) 14{ 15 FILE *fp = fopen("score.txt", "r"); 16 if (fp == NULL) { perror("score.txt"); return 1; } 17 FILE *sf = fopen("score_r.txt", "w"); 18 if (sf == NULL) { perror("score_r.txt"); return 2; } 19 proc(fp, sf); 20 fclose(sf); 21 fclose(fp); 22}

投稿2020/08/08 10:54

kazuma-s

総合スコア8224

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

keeen

2020/08/08 13:34

procはまだ習っていませんが、勉強してみます。ありがとうございました。
kazuma-s

2020/08/08 13:40

proc は関数名だから func でも sub でも何でもいいです。勉強するなら再帰呼出しです。
guest

0

fprintf(fp,"%s %lf %lf",name,height,weight);

では、読み込んだ状態と、同等の出力は難しいと思います。
・・・桁落ちなどに対処して“%.1lf”等の桁指定が必要

投稿2020/08/08 10:15

cateye

総合スコア6851

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

keeen

2020/08/08 13:29

そうなんですね。てっきり読み込む部分は変えてはいけないと思い込んでいました。読み込む部分から変えてみます
SHOMI

2020/08/08 14:14

読み込む部分じゃないです
keeen

2020/08/09 03:11

失礼しました。fprintfはファイルへの書き込みでした。
guest

0

課題文は画像を使わず書き起こすようにしてください。そうしないと、同じような課題をしている方が検索でこの質問がみつからず、みんなの回答が有意義にいかされません。

私の方で書き起こしておきました。

  • 以下のテキストファイルscore.txtを読み込み、名前、身長、体重をそれぞれ読み取る。
  • 読み取った内容を下の行から順にscore_r.txtに書き出すプログラムを作成せよ
  • コードの中でfscanf、fprintf関数は1度のみ使用可能
  • ファイル名はex13_2.cとすること

score.txt

score.txt

1Tanaka 170.2 59.2 2Yasui 165.3 55.1 3Kotani 180.5 92.7 4Nakano 176.9 68.5 5Kikuoka 173.8 77.8

まず、**課題文自体に問題があります。**score.txtの内容は固定なのでしょうか?たぶんそうでは無いと思いますが、課題文にはそれが明記されていません。テキストの内容が固定であれば、出力も常に固定なので、無意味な物ができあがるだけです。ということで、固定ではないという前提にします。

固定文ではないするとscore.txtについての詳しいフォーマットについての記載が必要です。また、フォーマットが定まったとして、イレギュラーは全く考慮しなくてもいいのか、エラーで終了するのか、でもコードが全く違います。それを明記すべきです。

次に、フォーマットについてですが、それぞれの項目についてどのような文字列が入るのか、区切りは固定なのか、改行コードはなんなのかです。

特に、一番最初の名前の所は一体何文字なのかが非常に重要です。例えば、「最大20文字、ただし合字の文字数は1文字ではなく構成している文字を数え上げるとする、日本で使用される全ての漢字を含む(ただしUnicodeに含まれていない物を除く)、テキストはUTF-8」と言う情報があってはじめて、名前の所はchar[81]あれば十分とわかります。それがないと、メモリが許す限りどんなに長い名前でも受け取れるように作る必要があります。この場合はコード量が全く違います。

慎重や体重の精度も問題です。例示されているのは小数点数1位までですが、単純にdoubleを使うと超天元突破グレンラガン(身長は137億光年以上)とかは小数点数1位とかはあっさり無視される精度になります。取り得る大きさや精度も明確にすべきです。

最後に、fscanfとfprintfについて言及していますが、vfscanf、fscanf_s、vfprintf、fprintf_s、といった似たような関数については言及していません。これらを使えば、この制限は無意味です。

よって、私の結論としては「課題文に不備があるため、回答不可。課題文を練り直すことから始めるべきである」です。

投稿2020/08/09 02:35

raccy

総合スコア21739

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

keeen

2020/08/09 03:16

問題文に不備がある、というのは衝撃でした。おそらくscore.txtの内容は固定で、ひっくり返して出力するだけの課題だと思います。
raccy

2020/08/09 03:22

引用元の明記がないので、課題はあなたが考えたのではないのですか?
kazuma-s

2020/08/10 11:00

問題文に不備があるとは、私は思いません。 基本的なプログラミングを学習するのが目的なので、あらゆる入力に対して頑強な、安全なコードを書くことは要求されていないでしょう。 問題文にない制約は、学習者が適当に決めて構わないと思います。 例えば、名前は 20バイト未満で収まるものとする。 ファイルの行数は 1000行未満とする。 身長や体重の値は、常識的な値とする。 などと想定してかまわないのではないでしょうか。
raccy

2020/08/10 11:29

> kazuma-sさん もし、これが、「将来プログラマーになるための課題」であるのであれば、要件にないことを勝手に想像し、決めつけることはかなり不味いと思っています。実際の現場での要件も最初は穴だらけです。それに対して、要件を詰めずに想定だけで進めると、あとから「いあ、そうじゃない、もっと大きい値も受け取る必要がある」とか言われます。ときには、想定外の入力値をきっかけとした脆弱性が潜んでいることもあります。 質問者さんが何を想定して課題に取り組んでいるのか知りませんが、ただプログラミングを学ぶ、ではなく、将来プログラマーになることが目的なら、明記されていない要件を詰めるというのは非常に重要な訓練項目の一つではないでしょうか?(まぁ、ただ学んでいるだけで、将来プログラミングをしないなら、必要はありませんが)
guest

0

sf でfprintfしましょう

投稿2020/08/08 07:01

y_waiwai

総合スコア88042

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dodox86

2020/08/08 07:38

sfとは何でしょうか。意図不明と感じましたので、低評価しました。
dodox86

2020/08/08 07:42

失礼しました。sf = fopen("score_r.txt","w");のファイルポインタのことですね。そうではあっても質問の主旨は「逆順に保存するには」だと思います。 ※低評価は取り消しました。
y_waiwai

2020/08/08 10:41 編集

保存するためにはどーしたら、ってはなしなんだけど、 ホンマにそれで解決になるの?(低評価2)
dodox86

2020/08/08 10:55

質問文によると > その後別のファイルに逆順で書き出す、という部分に詰まっています。 とあります。「逆順」と「書き出す」のどちらが主に知りたいことなのか、と言うことなのだと思います。パッと考えると、逆順にすることの方が書き出すことより難しく、それゆえ質問になっているのでは。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問