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

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

ただいまの
回答率

87.34%

C言語 ファイル中の単語数、バイト数の計算について

解決済

回答 3

投稿

  • 評価
  • クリップ 0
  • VIEW 1,536

score 9

C言語を使いUNIXやLINUXのls, cd, wcのようなコマンドをじぶんで作成しようとしています。現在やっているのは wc file のようなコマンドを実行した時に 3 3 25 という結果を返す関数を作ろうとしています。返り値の数字は左から行、単語数、バイト数です。以下のコードが自分で作成しているものですが、最初の行数以外が現状は正しい結果を返していません。

試したこととしては単語数の計算についてはスペース、改行、タブを確認し数えようとしていますが、結果は常に0となってしまいます。以下の写真が実行例です。

バイト数の計算についてはfseek関数を使いファイル中のバイト数をしゅとくしようとしました。

イメージ説明 
こちらがファイルの中身です。
イメージ説明

ファイル中の単語数の計算、バイト数の計算についてアドバイスをいただけますと幸いです。
宜しくお願いします。

int smallsh_wc(char **args){
    // Declaring the file pointer
    FILE *fp;
    char buffer[2000];
    int line = 0; //int word = 0; 
    int count = 0;

    // check file is open or not
    if((fp = fopen(args[1], "r")) == NULL){    
        printf("can not open file. %s\n", args[1]);
        exit(2);                   
    }

    // fgets read 1 line by stream
    /* count the line in the file */
    while(fgets(buffer, 2000, fp) != NULL){ 
        line++;
    }
    printf("%d ", line);

    /* count the word in the file */
    while(fgets(buffer, 2000, fp) != NULL){ 
        if(fgets(buffer, 2000, fp) == ' '){
            count++;
        }
        if(fgets(buffer, 2000, fp) == '\n'){
            count++;
        }
        if(fgets(buffer, 2000, fp) == "\t"){
            count++;
        }
    }
    printf("%d ", count);

    fseek(fp, SEEK_SET, SEEK_END);
    printf("%d \n", args[1], ftell(fp));

    fclose(fp);
    return 1;
}
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 3

checkベストアンサー

+1

バイト数とのことなので、

if((fp = fopen(args[1], "r")) == NULL){

ここでのオープンは、"r" で無く、"rb" としましょう。(バイナリRead)

あとは、

    int totalCount = 0;        /* 総バイト数 */
    int wordCount = 0;        /* 単語? 数 */
    int lineCount = 0;        /* 行数 */
    int lastIsSpace = 1;    /* 直前の文字の種類 ... 空白文字で0以外 */
    int ch = fgetc(fp);        /* 最初の文字読み込み */
    while (EOF != ch) {
        totalCount++;
        if (isspace(ch)) {
            if (!lastIsSpace)    wordCount++;
            if (ch == '\n')        lineCount++;
            lastIsSpace = 1;
        } else {
            lastIsSpace = 0;
        }
        ch = fgetc(fp);
    }


辺りでしょうか?

細かなチェックはしてません。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/11/01 20:36

    ファイルの最後が改行で終わっていない場合、ちょっと問題あり。
    対応はできるけど、特にコメントも無いようなので、課題として。

    キャンセル

+1

printf("%d ", line);の直前までの時点でファイルの内容を全て読み込んだでしょうから,
以降のfgets(buffer, 2000, fp)は全て失敗しているのではないでしょうか.

また,ftell()の返す値はテキストモードのファイルでは未規定とのことなので,ファイルサイズの取得には使えません.

{行数,単語数,ファイルサイズ}という各要素を個別に求めるのでなく,一度にやれば良いかと思います.
1行読込む毎に

  • 行数をインクリメント
  • 読み込めた行の内容を調べて単語数を加算
  • 読み込めた行の内容を調べてファイルサイズを加算

という感じで.

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

+1

ファイルを1バイトずつファイル終わりまで読みながら、全部の数をカウントするのがいいです。

・バイト数を+1
・改行文字なら行数を+1
・空白文字か非空白文字かを判断し、空白文字から非空白文字に切り替わる時点で、単語数を+1
・ファイルの最初と最後の部分はよく考える。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

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

関連した質問

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