🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C

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

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

Q&A

解決済

3回答

991閲覧

テキストファイルを読み込み、先頭から 3 名ずつでグループ分けを行い、数値 n が入力されるとn番目のグループの氏名を表記するプログラム

ksyiwk

総合スコア24

C

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

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

0グッド

0クリップ

投稿2019/10/29 08:28

C言語においてテキストファイルを読み込んで先頭から3名ずつでグループ分けを行い、数値nが入力されると実行例のようにn番目のグループの氏名を表記するプログラムを作成したいのですがどうしてもうまくできません。どなたか教えてください。テキストファイルには以下の内容が記載されています。
tsuzuki arai mizusako nonomura somei sudo sado kohara

int main(){ int n; char a[100][8]; FILE *fp; int i=0; fp = fopen("prog02.txt","r"); if(fp==NULL){ printf("file open failed.¥n"); return -1; } printf("グループ番号nを入力してください。\n"); scanf("%d",&n); if(n>3){ printf("ERROR\n"); }else { for(i=n;i<n+2;i++){ fgets(a[i],8,fp); printf("%s",a[i]); } } printf("\n"); fclose(fp); return 0; }

<実行例>
グループ番号nを入力してください。
2
nonomura somei sudo

グループ番号nを入力してください。
5
ERROR

グループ番号nを入力してください。
3
sado kohara

グループ番号nを入力してください。
0
Exit

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

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

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

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

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

jimbe

2019/10/29 08:47 編集

テキストファイルに書かれているという8名の名前は, ご質問に書かれているようにスペースで区切って1行に書かれているのでしょうか. それとも, 1行に1名ずつ8行に書かれているのでしょうか.
ksyiwk

2019/10/29 08:50

スペースで区切って1行に書かれています。
jimbe

2019/10/29 08:58

であれば fgets(a[i],8,fp) では(長さの違う)各名前を配列に取得できませんが, それについては何か代替方法はご存じでしょうか. もしくは, "スペースで区切られた文字列をスペースで分解する"方法は如何でしょうか.
ksyiwk

2019/10/29 09:33

fscanf(fp,"%s ",a[i]); printf("%s ",a[i]); としたのですが どの数値を入れても最初の三人の名前しか出てきません
kaina

2019/10/29 10:01

これpaizaの問題っぽいけど、大丈夫ですか? 違ったらごめんなさい。
guest

回答3

0

名前は 8個で、グループの個数は 3個とは限りません。
mushanokoji のように長い名前があるかもしれません。
まずは、名前を読み込みましょう。

C

1#include <stdio.h> 2 3int main(void) 4{ 5 char name[100][16]; // 100人分。1つの名前は15文字まで。 6 int nn = 0; // 名前の個数 7 FILE *fp = fopen("prog02.txt", "r"); 8 if (fp == NULL) { puts("file open failed"); return 1; } 9 while (nn < 100 && fscanf(fp, "%s", &name[nn]) == 1) 10 nn++; 11 fclose(fp); 12 // for (int i = 0; i < nn; i++) puts(name[i]); // 確認用 13}

人数が nn人で、名前の番号が 0~(nn - 1)。
グループの個数を gn とすると、gn = (nn + 2) / 3; で求まります。

さて、グループ番号 n が入力された時、
・n が 0以下なら終了。
・n が gn より大きければ、エラー表示
・そうでなければ、グループ番号 n に属する名前の先頭を a、最後を b とすると、
- n が gn より小さい場合は、a = (n - 1)*3, b = a + 2
- n が gn の場合は、a = (n - 1)*3, b = nn - 1
name[a] から name[b] までを表示

以上を繰り返す。

これをもとにコードを書いてみて、疑問点を質問に追加してください。

投稿2019/10/30 02:08

kazuma-s

総合スコア8224

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

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

0

ベストアンサー

fscanf(fp,"%s ",a[i]);

printf("%s ",a[i]);
としたのですが どの数値を入れても最初の三人の名前しか出てきません

ループの変数 i が幾つから開始しても, やっていることは「一人読んで表示する」だけですので, 最初の三名しか出ないのは当然です.
「表示するグループの先頭になるまで読み捨てる」処理が必要ではないでしょうか.

なお, C の文字列の格納には, 実際に文字が格納される領域の他に, 文字列の終わりを示す '\0' が入る領域が必要です.
最大 8 バイトの文字列が入るのでしたら, 9 バイト(以上)の領域を用意してください.

投稿2019/10/29 09:52

編集2019/10/29 09:56
jimbe

総合スコア13202

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

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

ksyiwk

2019/10/30 01:02

for(i=0;i<3;i++)という風にしたら出来ました。ありがとうございました。
kazuma-s

2019/10/30 02:06

質問を編集して、「できたコード」を追加してもらえませんか?
guest

0

やり方が分からない場合は、まず「(プログラムでなく)自分の手でやるとしたらどうやるか」を考えましょう。そのやり方を元にプログラムを組むのです。

こんな思考実験を考えましょう。

  • 短冊に一人の名前が書いてある
  • 短冊は8枚ある
  • 短冊を3人毎のグループにして仕分けする

手順としては

  1. 短冊の束の一番上の一枚を右手で取って、左手に(順番を崩さずに)移す
  2. もし今左手にある短冊が3枚になったら、一つのグループとして分けて置く
  3. 短冊がなくなるまで1、2をくり返す
  4. 短冊がなくなったときに左手に短冊を持っていたら、それを別のグループとして分けて置く

という感じになります。
基本的にはこれと同じ事をプログラムでやれれば、グループ分けはできるはずです。
※そもそもですが、テキストファイルには「1行に1名」で書いてあるのでいいのですよね?

投稿2019/10/29 08:45

tacsheaven

総合スコア13703

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問