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

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

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

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

Q&A

1回答

4079閲覧

ファイルの先頭から指定した行数分表示するときコマンド数が2の時10行表示するには

退会済みユーザー

退会済みユーザー

総合スコア0

C

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

0グッド

0クリップ

投稿2017/11/02 11:41

>conhead test.c -n5で→test.c ファイルの中身を先頭から5行表示するプログラムで  >conhead test.cとしたとき、デフォルトで10行表示したいのですが、うまくいきません。main()のelse if(argc<3)を書き換えればいいと思うのですが、どのようにすればいいでしょうか。 コード #include <stdio.h> #include <stdlib.h> // exit()のため必要 #include <string.h> int put_data(int m) { FILE *fin; FILE *fout; char InputFileName[256]; // 読み込みファイル名 char OutputFileName[256]; // 書き出しファイル名 char textbuffer[512]; // テキストを読み込む作業用文字列 int line_no=1; printf("読み込みファイル名 : "); gets(InputFileName); // 読み込みファイル名の取得 printf("書き出しファイル名 : "); gets(OutputFileName); // 書き出しファイル名の取得 fin=fopen(InputFileName,"r"); if (fin==NULL) { printf("can't open file <%s>\n",InputFileName); exit(1); //ファイルオープンエラーで緊急停止 } fout=fopen(OutputFileName,"w"); if (fout==NULL) { printf("can't open file <%s>\n",OutputFileName); exit(1); //ファイルオープンエラーで緊急停止 } while (line_no < m) { fgets(textbuffer,512,fin); //ファイル読み込みエラーでない限り //fgets(textbuffer,512,fin)とはファイルfinから一行読み込み, //文字配列textbufferに保存しなさいの意味。 //ただし,文字列長制限があり511文字まで fprintf(fout,"%04d %s",line_no,textbuffer); fprintf(stdout ,"%04d %s",line_no, textbuffer ); line_no++; } m=0; fclose(fin); fclose(fout); return 0; } void copy(FILE *src, FILE *dst); // srcが指す文字列をdstが指す配列にコピーする。 int max = 11; int main(int argc,char* argv[]) { char *max,*max1; int m; FILE *fp; if(argc<2) { copy(stdin, stdout); // コマンドライン引数が1のとき } else if(argc<3) { // コマンドライン引数が2のとき fp =fopen(argv[1], "r"); copy(fp, stdout); fclose(fp); } else if(argc<4) { // コマンドライン引数が3(C:\Users\username\chap09\kadai>conhead abc.c -n5)のとき m=strlen(argv[2]); if(m==3){ max=&argv[2][2]; m=*max-'0'; printf("mは「%d」です\n",m); ++m; } if(m==4){ max =&argv[2][2]; max1=&argv[2][3]; m=*max-'0'; m =m*10 + *max1-'0'; printf("mは「%d」です\n",m); ++m; } put_data(m); } return 0; } void copy(FILE *src, FILE *dst) // srcが指す文字列をdstが指す配列にコピーする。 { int ch; int i; int max; while ((ch = fgetc(src)) != EOF) { fputc(ch, dst); if(ch == '\n') //改行をカウント i++; if(i == max) break; } } /* 実行時のコンソール画面 C:\MinGW\users\chap09\kadai>gcc -I. -o kad9-5 kad9-5.c pdcurses.a C:\MinGW\users\chap09\kadai> kad9-5 a.c -n8 mは「8」です 読み込みファイル名 : a.c 書き出しファイル名 : b.txt 0001 /*プログラムソースファイルを行ごとに読み込んで,行頭に行番号 をつけて,テキストファイルに書き出す。 0002 0003 あらかじめチェック用プログラムソースファイル「a.c」をテキス トエディタでつくってから実行し, 0004 「b.txt」が出来たことを確認して,テキストエディタで「b.txt」 を見るとよい。 0005 0006 関数fgets()は,ファイルから一行を読み込み文字列にする。 0007 一行とは,改行文字があるところまでの文字列。 0008 C:\MinGW\users\chap09\kadai>

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

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

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

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

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

guest

回答1

0

copy関数内のmaxの値が不定です。(グローバル変数maxとここのmaxは別物です。)

C

void copy(FILE *src, FILE *dst)
{
int ch;
int i;
int max;

while ((ch = fgetc(src)) != EOF) {

fputc(ch, dst); if(ch == '\n') //改行をカウント i++; if(i == max) break; }

}

引数maxを追加するのが最もシンプルに思えます。
グローバル変数を使っても解決出来ますが、あまり良い作法とは言えないでしょう。

ついでに言うと、iの値が不定なのもよくないですね。
何らかの変数を参照する際には、適切に初期化されているか確認する癖をつけた方が良いです。


適当に作ってみました。

C

1void copy(FILE *src, FILE *dst, int max) { 2 char ch; 3 for(int i = 0; i < max; i++) { 4 while((ch = fgetc(src)) != '\n') { 5 if(ch == EOF) return; 6 7 fputc(ch, dst); 8 } 9 fputc('\n', dst); 10 } 11}

Cではデフォルト引数が(確か)使えないので、10という数値は呼び出し側で指定してください。
デフォルト引数もオーバーロードも工夫なしに使えないのは不便ですね...

投稿2017/11/02 11:54

編集2017/11/02 12:10
LouiS0616

総合スコア35660

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

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

退会済みユーザー

退会済みユーザー

2017/11/02 12:03

こんばんわ いつもお世話になっています。通常は-n8で行数を指定するのですが、指定しない場合は10行表示するようにしたいのですが。
LouiS0616

2017/11/02 12:14

-nオプションのない場合は呼び出し側で10を指定するのが最もシンプルです。 工夫次第でいろいろ出来ないことはないですが、この『デフォルト値10』という情報をmain関数が知っていてもそんなに問題はない気がします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問