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

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

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

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

Q&A

5回答

1178閲覧

ファイル名指定のファイルの行数と文字数

Taka787

総合スコア23

C

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

0グッド

0クリップ

投稿2018/05/29 01:13

前提・実現したいこと

コマンド行引数として与えられたファイル名をもつファイルの中身を調べ、 その行数と文字数(改行文字も文字として数える)とをこの順に標準出力に書き出します。 行数と文字数は、それぞれ、左詰にして1行として書き出します。

コマンド行に引数が1個与えられたのでないときは、 「argc!=2」と左詰にして1行として標準出力に書き出すとともに、 コマンド行に与えられた引数全てを、与えられた順に、 それぞれ左詰にして1行として標準エラー出力に書き出し、 その後で exit(-1); によって実行を打ち切ります。また、引数が1個与えられていても、それをファイル名としてファイルを開くことができなかったときは、標準出力に「can't open:」の後ろに空白1文字に続けてその引数を書き出して改行したのちに、exit(-1); によって実行を打ち切ります。

発生している問題・エラーメッセージ

思う通りに動作しません。

該当のソースコード

#include <stdio.h> #include <string.h> int main(int argc, char *argv[]) { #define LINESIZE 100 FILE *f; char line[LINESIZE]; int i; int x; int n; if( argc!=2 ) { printf("argc!=2\n"); for(i= 1; i<argc; i++) { fprintf(stderr, "%s\n", argv[i]); } exit(-1); } n= atoi(argv[1]); f = fopen(n, "rw"); if( argc==2 && f== NULL ) { for(i= 1; i<argc; i++) { printf("can't open: %s\n", argv[i]); } exit(-1); } for(i= 1; fgets(line, LINESIZE, f)=='\n'; i++) { for(x= 0; line[x]!=NULL; x++); } } printf("%d\n%d\n", i, x); fclose(f); return 0; }

補足

一応自分でも書いてみました。ご教授お願いします。

ここにより詳細な情報を記載してください。

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

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

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

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

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

y_waiwai

2018/05/29 01:25

思う通りに動かないとは、どういうふうに動くのでしょうか
Taka787

2018/05/29 01:39

コンパイルエラーではじき返され全く動作しません。
y_waiwai

2018/05/29 01:40

エラーメッセージをそのままコピペして、質問に追記してください
Taka787

2018/05/29 02:01

8-3.c: In function 'main': 8-3.c:17:9: warning: implicit declaration of function 'exit' [-Wimplicit-function-declaration] exit(-1); ^ 8-3.c:17:9: warning: incompatible implicit declaration of built-in function 'exit' [enabled by default] 8-3.c:20:5: warning: implicit declaration of function 'atoi' [-Wimplicit-function-declaration] n= atoi(argv[1]); ^ 8-3.c:21:5: warning: passing argument 1 of 'fopen' makes pointer from integer without a cast [enabled by default] f = fopen(n, "rw"); ^ In file included from 8-3.c:1:0: /usr/include/stdio.h:272:14: note: expected 'const char * __restrict__' but argument is of type 'int' extern FILE *fopen (const char *__restrict __filename, ^ 8-3.c:26:9: warning: incompatible implicit declaration of built-in function 'exit' [enabled by default] exit(-1); ^ 8-3.c:29:39: warning: comparison between pointer and integer [enabled by default] for(i= 1; fgets(line, LINESIZE, f)=='\n'; i++) { ^ 8-3.c:30:26: warning: comparison between pointer and integer [enabled by default] for(x= 0; line[x]!=NULL; x++); ^
Taka787

2018/05/29 02:02

y_wakiwaiさん このようなものが出てます。
Taka787

2018/05/29 04:31

もう少しヒントを頂けますか⁇
a_saitoh

2018/05/29 06:20

for(i= 1; i<argc; i++) とありますが、コマンドライン引数ファイル名を複数指定することもできるようにしたいのですか?現状だと argc==2をチェックしてからこのfor文に行ってるので、1回しかループしません。
guest

回答5

0

kaztoさんの回答以外で気になったところ。

if( argc==2 && f== NULL ) {

しょっぱなでargc!=2はエラーにしているので、ここでargc==2の必要はないでしょう。

for(i= 1; fgets(line, LINESIZE, f)=='\n'; i++) {

fgetsの戻り値はchar*です(参考
ファイルの終端か否かを判定するのであれば、NULLと比較しましょう。
またfor文の2番目はループ条件です。
なので!=NULLとするべきです。

for(x= 0; line[x]!=NULL; x++);

xは文字数のカウンターと思われますが、ここで毎回0を入れているので、行内の文字数しかカウントできていません。

投稿2018/05/29 02:06

ttyp03

総合スコア16996

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

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

0

コンパイルエラーについて。
閉じかっこの整合が取れていません。

C

1 for(i= 1; fgets(line, LINESIZE, f)=='\n'; i++) { 2 for(x= 0; line[x]!=NULL; x++); 3 4 } /* ← 不要 */ 5 }

次に、ファイルを開くところで、
fopenの引数に整数を与えており、意味不明です。

C

1 n= atoi(argv[1]); 2 f = fopen(n, "rw");

投稿2018/05/29 01:50

編集2018/05/29 02:11
kazto

総合スコア7196

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

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

Taka787

2018/05/29 02:01

argv[1]は引数の1個目を読み込みたいので指定しているのですけれど 間違えなのでしょうか?
kazto

2018/05/29 02:07

言葉足らずでした。 atoiを用いてコマンドライン引数1つめを整数に変換します。 次に、その整数を、fopenの関数引数に与えている、この部分が意味不明、という意図でした。
guest

0

参考情報

  • Source of the wc command

https://www.gnu.org/software/cflow/manual/html_node/Source-of-wc-command.html

ファイルの文字数、単語数、行数を数える wc という linux のコマンドのソース例です。

投稿2018/05/30 12:56

katoy

総合スコア22322

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

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

0

一応いいところまで来たのですが、あと一つだけ問題があります。
それは、一つだけ空白を入れた時の行数の個数を0にしたいのですが、結果は、行数:1 文字数:1 と表示されます。どうすれば直るでしょうか?

#include<stdio.h> #include<stdlib.h> int main(int argc, char *argv[]) { int i; if( argc!=2 ) { printf("argc!=2\n"); for(i= 1; i<argc; i++) { fprintf(stderr, "%s\n", argv[i]); } exit(-1); } #define BUF_SIZE 256 char buf[BUF_SIZE]; FILE* fp; int contentsLen; int line = 0; fp = fopen(argv[1], "r"); if(fp==NULL) { printf("can't open: %s\n", argv[1]); exit(-1); } if(fp == NULL) exit(1); fseek(fp,0,SEEK_END); contentsLen = ftell(fp); fseek(fp,0,SEEK_SET); while (fgets(buf, BUF_SIZE, fp) != NULL) { line++; } } fclose(fp); printf("%d\n%d\n", line, contentsLen); return 0; }

投稿2018/05/29 05:24

Taka787

総合スコア23

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

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

y_waiwai

2018/05/29 05:28

行数1、文字数1で合ってるのではないですか? 空白のときは特別な処理をさせたいのでしょうか
Taka787

2018/05/29 05:31

はいそうです。空白の時だけそうしたいのですが
y_waiwai

2018/05/29 05:37

なら、空白が一つだけ、というのを判定して、それぞれ0を返す、という処理を追加すればいいですね
y_waiwai

2018/05/29 05:41

最初のopenのあと、bufにファイルの最初の数バイトを読み込ませ、読み込んだバイト数が1で読み出しデータが空白というのを判定すればいいことになります
Taka787

2018/05/29 05:54

分かりました。今試してみます。
Taka787

2018/05/29 06:03

すみません。初心者なもんではんていしきがおもいうかばないのですが・・・ もう少しヒントを頂けますか?
y_waiwai

2018/05/29 06:15

if(1==fread(buf,1,10,fp) ){ if(buf[0]==' '){ // 読み出し文字が1でかつスペース line=0; contentsLen=0; なんやかや... } }
Taka787

2018/05/29 09:46

何度もスミマセン。結果は変わりません(T_T) 例えば、見た目は何もない行でも実際には空白や改行が入ってるとline変数に1カウントしてしまうので、カウントしないようにしたいです。 どうすればよいでしょうか?
guest

0

8-3.c: In function 'main':

8-3.c:17:9: warning: implicit declaration of function 'exit' [-Wimplicit-function-declaration] exit(-1); ^
8-3.c:17:9: warning: incompatible implicit declaration of built-in function 'exit' [enabled by default]
8-3.c:20:5: warning: implicit declaration of function 'atoi' [-Wimplicit-function-declaration] n= atoi(argv[1]); ^
8-3.c:21:5: warning: passing argument 1 of 'fopen' makes pointer from integer without a cast [enabled by default] f = fopen(n, "rw"); ^ In file included from
8-3.c:1:0: /usr/include/stdio.h:272:14: note: expected 'const char * restrict' but argument is of type 'int' extern FILE *fopen (const char *__restrict __filename, ^
8-3.c:26:9: warning: incompatible implicit declaration of built-in function 'exit' [enabled by default] exit(-1); ^
8-3.c:29:39: warning: comparison between pointer and integer [enabled by default] for(i= 1; fgets(line, LINESIZE, f)=='\n'; i++) { ^
8-3.c:30:26: warning: comparison between pointer and integer [enabled by default] for(x= 0; line[x]!=NULL; x++); ^

  1. 8-3c 17行目 関数exit のプロトタイプ宣言がない

  2. 8-3c 20行目 関数atoi のプロトタイプ宣言がない

  3. 8-3c 21行目 関数fopen の第一引数の型が違う

  4. 8-3c 26行目 関数exit のプロトタイプ宣言がない

  5. 8-3c 29行目 ポインタと整数を比較している

  6. 8-3c 30行目 ポインタと整数を比較している

1,2,4 は、#include <stdlib.h> を追加すればOK
後はなにがまずいかは他の回答を参照のこと

投稿2018/05/29 05:07

y_waiwai

総合スコア87715

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

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

Taka787

2018/05/29 05:26

一応いいところまで来たのですが、あと一つだけ問題があります。 それは、一つだけ空白を入れた時の行数の個数を0にしたいのですが、結果は、行数:1 文字数:1 と表示されます。どうすれば直るでしょうか? #include<stdio.h> #include<stdlib.h> int main(int argc, char *argv[]) { int i; if( argc!=2 ) { printf("argc!=2\n"); for(i= 1; i<argc; i++) { fprintf(stderr, "%s\n", argv[i]); } exit(-1); } #define BUF_SIZE 256 char buf[BUF_SIZE]; FILE* fp; int contentsLen; int line = 0; fp = fopen(argv[1], "r"); if(fp==NULL) { printf("can't open: %s\n", argv[1]); exit(-1); } if(fp == NULL) exit(1); fseek(fp,0,SEEK_END); contentsLen = ftell(fp); fseek(fp,0,SEEK_SET); while (fgets(buf, BUF_SIZE, fp) != NULL) { line++; } } fclose(fp); printf("%d\n%d\n", line, contentsLen); return 0; }
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.51%

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

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

質問する

関連した質問