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

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

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

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

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Q&A

解決済

3回答

1910閲覧

ファイル入出力とプロフ

nisuko

総合スコア35

C

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

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

0グッド

0クリップ

投稿2016/01/16 03:06

編集2016/01/16 12:19

C

1#define _CRT_SECURE_NO_WARNINGS 1 2 3#include <stdio.h> 4#include <string.h> 5#include <stdlib.h> 6 7 8typedef struct profile{ 9 char name[20]; 10 char age[10]; 11 char sex[10]; 12}Pro; 13 14int main(){ 15 16 int i; 17 char filename[256]; 18 FILE *fp; 19 20 21 puts("プロフィールを設定します。\n" 22 "以下の項目を入力してください。"); 23 printf("何人分作りますか?>>>"); 24 scanf("%d", &i); 25 26 for (int h = 0; h != i ; h++){ 27 printf("%d人目のプロフィールを作ります。" 28 "以下の項目を入力してください。\n", h + 1 ); 29 30 Pro hito; 31 getchar(); 32 puts("ファイル名を入力してください。"); 33 fgets(filename, sizeof(filename), stdin); 34 filename[strlen(filename) - 1] = '\0'; 35 strcat(filename, ".txt"); 36 fp = fopen(filename, "w"); 37 38 puts("名前を入力してください。"); 39 fgets(hito.name, sizeof(hito.name), stdin); 40 hito.name[strlen(hito.name) - 1] = '\0'; 41 fprintf(fp,"名前は%s\n", hito.name); 42 43 puts("年齢を入力してください。"); 44 fgets(hito.age, sizeof(hito.age), stdin); 45 hito.age[strlen(hito.age) - 1] = '\0'; 46 fprintf(fp,"年齢は%s\n", hito.age); 47 48 puts("性別を入力してください。"); 49 fgets(hito.sex, sizeof(hito.sex), stdin); 50 hito.sex[strlen(hito.sex) - 1] = '\0'; 51 fprintf(fp,"性別は%s\n", hito.sex); 52 53 fclose(fp); 54 } 55 return EXIT_SUCCESS; 56} 57

このプログラムを走らせると、人数を1人に設定すると、.txtが作られ何もできずに終わり、2~にすると入力した人数-1人分のファイルを生成しようとし、名前が入力されたものだけ作られます。
また、ファイルは作られますが、ファイルの中に書き込む所はできません。puts→fscanfの処理が飛ばされます。

そして初心者なので一部、入門書に書かれてるファイルを生成するコードをコピーしています。
ファイル名を入力してください→fgets、strcatなどの処理のところです。

このコードをどうすれば人数分のファイル生成ができ、中身を書き込むことができますか?

説明が下手なのでもしかしたら意図が通じてない所もあるかもしれません。
それと、もともとコード自体を誰かに見せるつもりはなかったので、変数の名前はあまり気にしないでほしいです。すみません。

追記
コードを編集しました。
ここが間違ってる、ここはこうすると良いなどがあれば教えてください。
実行してみた感じでは思った通りに動いてくれました

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

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

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

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

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

guest

回答3

0

ベストアンサー

こんにちは。

fscanf(fp, ...)はfpが示すファイルからデータを読み込みます。書き出しではないです。
fgets()で標準入力から文字列を読み込み、fpus()でfpへ出力すれば良いと思います。

また、fp=fopen()に成功したらfclose(fp);する必要が有ります。(開いたら閉じる。鉄則です。)

投稿2016/01/16 03:43

Chironian

総合スコア23272

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

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

nisuko

2016/01/16 12:02 編集

fscanfではファイルに書き込めないのですね、、わかりました。fgetsなどを一度確認してきます。 fcloseは最後にしてたので大丈夫だと思いましたが、他の方と貴方の回答を見て納得しました。ありがとうございます。 追記 コード編集しました。確認をお願いします。
Chironian

2016/01/16 12:10

> コード編集しました。確認をお願いします。 基本的には良さそうです。(バッファオーバーフロー等の細かい問題はありますが、それは追々学習を進めて下さい。) ただ、名前等の後1行余分に改行されると思います。fgets()は改行まで入力されるからです。下記はその改行を0で上書きして削除する処理です。文字列の最後に改行('\n')か入るのです。 > filename[strlen(filename) - 1] = '\0';
nisuko

2016/01/16 12:21

確認ありがとうございます。 1行空くのは確かに気になっていたので、処理を追加しました。 こうでいいのですよね?動作は一応考え通りに動いてくれていますし、、。 バッファオーバーフローって取ってあった分のメモリからあふれるってやつですよね? 改善するにはunsigned int だったり配列でとる分を増やすだけでよいのでしょうか? 効果的な処理手法があるのでしょうか?
Chironian

2016/01/16 12:45

それで良いと思います。 > バッファオーバーフローって取ってあった分のメモリからあふれるってやつですよね? その通りです。 > 改善するにはunsigned int だったり配列でとる分を増やすだけでよいのでしょうか? 増やすだけですと、それを超えて入力されるとやはりバッファオーバーフローしてしまいます。 > 効果的な処理手法があるのでしょうか? 方法は色々あります。今回のケースの場合は、メモリ以上の長さの入力があったら残りを'\n'まで読み捨てると良いと思います。 あ、nisukoさんのプログラムはバッファオーバーフローは起きないですね。 長過ぎる名前等を入力すると、動作が可笑しくなるだけです。(どうなるかは実際にやってみるのが良いです。19文字の名前や20文字以上の名前など。) 「長過ぎる入力+配慮不足≒バッファオーバーフロー」なので短絡的に書いてしまいました。ごめんなさい。
nisuko

2016/01/17 00:19

ありがとうございます。 やってみると、名前で溢れた分は年齢へ、それも溢れると性別へ、という動作しました。 どのように対処するかまで教えていただきありがとうございます。
guest

0

for 内の fp = fopen(filename, "w"); で出力ファイルを人数分オープンしていますが、このfpのクローズは for の外(48行目)でしていますよね。
クローズもfor内で毎回、人数分する必要があります。

また、"名前を入力してください" の箇所も fscanf で fp を指定しているのも変と思います。

投稿2016/01/16 03:32

yoshi777

総合スコア674

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

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

nisuko

2016/01/16 12:02 編集

fcloseは毎回必要なのですね、確かに言われてみて、よく考えてみると毎回閉じなきゃおかしいですね。ありがとうございます。 fscanfを、独学なのですが、本で習った時には fscanf(fp,"%s",name) と書かれていたので必要だと思ったのですが、、 一度リファレンスを確認してみます、確認する癖をつけるようにします。 追記 コード編集しました。確認をお願いします。
guest

0

fscanf(fp, "%s", hito.namae);

は、fpでオープンしたファイルから読み込むということですが、やりたいことと違いますよね?
また、どこでもファイルに書いている箇所がありません。どこで書いているつもりですか?
プログラムを音読してみてはどうでしょうか。

投稿2016/01/16 03:24

otn

総合スコア84538

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

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

nisuko

2016/01/16 12:02 編集

説明を見る限りやりたいことと違います。 音読しました。わからないので3回やりましたがわかりません。 大体35か36行目辺りでfopenでファイルを生成("w"で、なければ生成する、と聞きました。)しており、そのしたのfscanfで、そのファイルに情報を書いてるつもりでした。 どうすればよいでしょうか?fscanfは入力関数じゃないのですか? 追記 コード編集しました。確認をお願いします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問