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

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

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

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

Emacs

GNU Emacsと拡張性の高い、高性能なテキストエディタです。豊富なライブラリの導入により、統合開発環境やWebブラウザとしても機能させる事が可能です。

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

Q&A

解決済

4回答

2916閲覧

C言語でテキストファイルを読み、入力された行数のテキストを表示するコード

退会済みユーザー

退会済みユーザー

総合スコア0

C

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

Emacs

GNU Emacsと拡張性の高い、高性能なテキストエディタです。豊富なライブラリの導入により、統合開発環境やWebブラウザとしても機能させる事が可能です。

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

0グッド

0クリップ

投稿2017/12/29 13:29

編集2017/12/29 14:09

###前提・実現したいこと
C言語でテキストファイルを読み、入力された行数のテキストを表示しようとしています。
例えば以下の「Hello.dat」というテキストファイルを読み、以下のように2行目と指定して実行すると、テキストファイルの2行目が表示されることを実現したいです。

txt

1//Hello.dat 2Hello world 3Hello C 4Hello world 5Hello C 6Hello world 7Hello C 8Hello world 9Hello C 10Hello world
./example Hello.dat 2 Hello C

###該当のソースコード
現状では、以下のコードを実行すると、テキストファイルの中身が全て表示されるコードは実装できています。これをどのように変更していけばいいかわからず、困っています。

C

1#include <stdio.h> 2int main(){ 3 FILE* fp; // file pointer 4 char tmpline[256]; // temporary space 5 fp = fopen("Hello.dat", "r"); // open a file 6 if (fp != NULL) { 7 while (fgets(tmpline, 256, fp)){ 8 if (tmpline != NULL){ 9 printf("%s", tmpline); 10 } 11 } } 12 fclose(fp); 13 return 0; }
% ./example r ファイルのデータが全て表示される

###試したこと
以下のようなfor文を用いたコードを実行したところ、エラーが出てしまいました。

c

1//trial.c 2#include <stdio.h> 3int main(){ 4 FILE* fp; // file pointer 5 6 char tmpline[256]; // temporary space 7 8 fp = fopen("Hello.dat", "r"); // open a file 9 10 if (fp != NULL) { 11 for(int i = 0; fgets(tmpline, 256, fp); ++i){ 12 printf("%d : %s", i, tmpline); 13 } 14 } 15 16 fclose(fp); 17 return 0; }
% gcc -Wall trial.c -o trial trial.c: In function 'main': trial.c:7:5: error: 'for' loop initial declarations are only allowed in C99 mode for(int i = 0; fgets(tmpline, 256, fp); ++i){ ^ trial.c:7:5: note: use option -std=c99 or -std=gnu99 to compile your code

###補足情報(言語/FW/ツール等のバージョンなど)
GNU Emacs 22.1.1

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

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

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

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

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

guest

回答4

0

ベストアンサー

ご提示プログラムすこし加えました、ご参考まで

c

1#include <stdio.h> 2int main(int argc, char *argv[]){ 3 FILE* fp; // file pointer 4 int i,j; 5 char tmpline[256]; // temporary space 6 if (argc < 3){ 7 printf("パラメータ数エラー %d\n",argc); 8 return -1; 9 } 10 11 char *fname = argv[1]; 12 j = atoi(argv[2]); 13 if (j == 0) { 14 printf("ライン数エラー\n"); 15 return -1; 16 } 17 18 fp = fopen(fname, "r"); // open a file 19 if( fp == NULL ) { 20 printf( "ファイルオープンエラー\n" ); 21 return -1; 22 } 23 for (i=1; fgets(tmpline, 256, fp) != NULL; i++){ 24 if ( i == j ){ 25 printf("%s", tmpline); 26 } 27 } 28 fclose(fp); 29 return 0; 30}

投稿2017/12/29 14:23

A.Ichi

総合スコア4070

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

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

退会済みユーザー

退会済みユーザー

2017/12/30 00:41

ご回答いただきましてありがとうございました。
退会済みユーザー

退会済みユーザー

2017/12/30 00:43

if (argc < 3){ printf("パラメータ数エラー %d\n",argc); return -1; } の部分に関して3以下とされているのは、何故でしょうか。
A.Ichi

2017/12/30 00:52 編集

./example Hello.dat 2 とした場合パラメータは3個です。最後の数値が無い場合にargv[2]を参照すると、アドレス例外になるので、これを避ける為です。多い分にはエラーとしていません。
退会済みユーザー

退会済みユーザー

2017/12/30 00:54

わかりました。丁寧なご回答とご説明をありがとうございました。
guest

0

一歩ずつ進みましょう。
「int型変数iを1から10までカウントアップして、2のときだけ表示する」
というプログラムをまず作ってみましょう。

投稿2017/12/29 13:44

otn

総合スコア84538

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

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

退会済みユーザー

退会済みユーザー

2017/12/29 13:50

for(int i= 1; i<=10; ++i){ if (i == 2){ printf("%s", tmpline); } } でしょうか。
otn

2017/12/29 13:58

これがすっと出来るのに、元の質問がわからないというのは、どの部分がわからないのでしょうか? int main() と書いていると言うことは、コマンドライン引数が分からないんですかね。 コマンドライン引数の1番目は、int main(int argc, char **argv){ ~と書いて、 argv[1] で参照できます。引数があるときにはargcが2以上になるので、それも確認します。 argv[1] は文字列なので、intにするにはatoi()等を使います。
退会済みユーザー

退会済みユーザー

2017/12/30 00:40

ご回答いただきましてありがとうございました。
guest

0

ステップ1

main関数を以下のように変更して、引数の数と引数の文字列を受け取れるようにする。
受け取ったら引数の数をチェックしておこう。
引数の数が2個ならargcには3が入る。なぜなら、argv[0]にはコマンド名が入り、引数はargv[1]から入るのでカウントが1個多くなる。

C

1main(int argc, char *argv[])

ステップ2

引数は文字列で渡されるので、行数にあたる2番目の引数を数値に変換する。
1番目の引数は文字列なのでそのまま使える。
Cの標準ライブラリには文字列をintに変換する関数atoi(3)が用意されている。
以下をソースの先頭に追加すれば使用できる。

C

1#include <stdlib.h>

ステップ3

ファイルを1行読み込む度に回数をカウントする。
それが行数と一致したときだけprint文を実行する。

投稿2017/12/29 13:43

編集2017/12/29 14:48
hichon

総合スコア5737

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

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

退会済みユーザー

退会済みユーザー

2017/12/29 14:28

ご回答いただきましてありがとうございます。ステップ2がまだ十分に理解できていません。 #include <stdio.h> int main(int argc, char *argv[]){ FILE* fp; // file pointer char tmpline[256]; // temporary space fp = fopen("Hello.dat", "r"); // open a file if (fp != NULL) { for(int i= 1; fgets(tmpline, 256, fp); ++i){ if (i == argc){ printf("%s", tmpline); } } } fclose(fp); return 0; } 現状で理解できている範囲でコードを書いたものです。
hichon

2017/12/29 14:49 編集

ステップ2に追記しました。 2番目の引数はargv[2]に文字列で入っています。
退会済みユーザー

退会済みユーザー

2017/12/30 00:39

追記のご説明をいただきましてありがとうございました。 大変助かりました。
guest

0

一番簡単な方法は、whileループをforループに置き換えることだと思います。
あまりにも愚直ですが、これなら直感的に記述可能ですね。

C

1for(int i = 1; fgets(tmpline, 256, fp); ++i){ 2 printf("%d行目: %s", i, tmpline); 3}

なお、コマンドラインから引数を受け取りたい場合は、次のように書けばよいでしょう。

C

1int main(int argc, char **argv) { 2 if(argc < 3) { 3 printf("USAGE: .exe filename line_num\n"); 4 return -1; 5 } 6 7 char *filename = argv[1]; 8 int row_num = atoi(argv[2]); 9 10 if(row_num < 1) { 11 return -1; 12 } 13 14 後略

追記

以下のようなfor文を用いたコードを実行したところ、エラーが出てしまいました。

原因と解決策がもろに書いてあります。まずは表示されたものを読んでください。
単語は日頃カタカナで使うものばかりですし、文法は中学生レベルです。

trial.c:7:5: error: 'for' loop initial declarations are only allowed in C99 mode
trial.c:7:5: note: use option -std=c99 or -std=gnu99 to compile your code

オプションを変えるか、for文の初期化部分を少し書き換えれば良いです。

投稿2017/12/29 13:37

編集2017/12/29 14:10
LouiS0616

総合スコア35660

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

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

退会済みユーザー

退会済みユーザー

2017/12/29 14:11

ご回答いただきましてありがとうございます。試したことに、for文を用いたコードとコンパイルエラーを明記させていただきました。可能であれば、このエラーに関してもアドバイスいただけますと幸いです。
LouiS0616

2017/12/29 14:39

回答に追記した通りです。
退会済みユーザー

退会済みユーザー

2017/12/30 00:39

ご回答いただきましてありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問