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

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

ただいまの
回答率

90.61%

  • C

    3572questions

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

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

受付中

回答 5

投稿

  • 評価
  • クリップ 0
  • VIEW 275

Hisa-pon777

score 3

 前提・実現したいこと

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

 補足

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

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

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • Hisa-pon777

    2018/05/29 11:02

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

    キャンセル

  • Hisa-pon777

    2018/05/29 13:31

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

    キャンセル

  • a_saitoh

    2018/05/29 15:20

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

    キャンセル

回答 5

+1

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

    for(i= 1; fgets(line, LINESIZE, f)=='\n'; i++) {
        for(x= 0; line[x]!=NULL; x++);

        } /* ← 不要 */
    }

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

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

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/05/29 11:01

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

    キャンセル

  • 2018/05/29 11:07

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

    キャンセル

+1

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を入れているので、行内の文字数しかカウントできていません。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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 14: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;
    }

    キャンセル

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 14:28

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

    キャンセル

  • 2018/05/29 14:31

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

    キャンセル

  • 2018/05/29 14:37

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

    キャンセル

  • 2018/05/29 14:41

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

    キャンセル

  • 2018/05/29 14:54

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

    キャンセル

  • 2018/05/29 15:03

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

    キャンセル

  • 2018/05/29 15:15

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

    キャンセル

  • 2018/05/29 18:46

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

    キャンセル

0

参考情報

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 90.61%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • C

    3572questions

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