【18日AM1時~5時】メンテナンスのお知らせ

プログラミングC言語についてです
こちらの問題がわかりません
どなたか詳しい方、ご解答をお願いします。
実行時に main 関数の引数としてファイル名(つまり,文字列 1 つ)を受け取り,与えられた名前のテキストファイルの文字数・行数・ファイル名をタブ文字で区切って表示するプログラムを作成せよ.実行時に与えるテキストファイルは,ASCII 文字のみからなるものとし,実行ファイルと同じディレクトリに存在するものとする。

ヒント
行数 = 現れる改行文字の個数 + 1

実行例
$ cat testdata
book boots
cat dog horse
car bus train
$ ./prob2 14-2-data.txt
38 3 14-2-data.txt

教えて!goo グレード

A 回答 (9件)

この質問は「知恵袋」にあったこの問題でしょうか。

(私の解答を書き込んでおきましたが)

#include <stdio.h>

int main(int argc, char *argv[])
{
FILE *file;
int tmp; /* 読み込んできた1文字を入れる変数 */
int c = 0; /* 読み込んだ文字数をカウント */
int l = 1; /* 行数をカウント */

if (argc != 2) {
fprintf(stderr, "Error: too few or much arguments");
return 1;
}
//プログラムを完成してください。

if ((file = fopen(argv[1], "r")) == NULL) {
fprintf(stderr, "Error: File cannot be opened");
return 1;
}

int saigo; /* ファイルの最後の1文字を入れる変数 */

for (; (tmp = fgetc(file)) != EOF; c++, saigo = tmp) {
if (tmp == '\n')
l++;
}

fclose(file);

if (c == 0 || saigo == '\n')
l--;

/* または
if (c == 0) {
fprintf(stderr, "Error: File is 0 bytes");
return 1;
}
if (saigo == '\n')
l--;
*/

printf("%d\t%d\t%s\n", c, l, argv[1]);

return 0;
}

最初に、l = 1 としているのも違和感がありますが。やっぱり、問題文がおかしいですね。
「プログラミングC言語について次の問題がわ」の回答画像9
    • good
    • 0

申し訳ありません。

テキストファイルが0バイトの場合を考えていませんでした。0バイト対策は、for を抜けた後の if を次のようにしてください。

if (mojisu != 0 && saigo != '\n')
gyosu++;

私は、問題文がおかしいというために適当なプログラムを作り投稿しましたが失敗でした。

プログラムでどこまで対応すべきなのか考えないといけませんが、テキストファイルではなくバイナリファイルだった場合どうするの?とか考えればきりがないといいますか。

回答の投稿は「問題文がおかしいと思います」の一言で終わりにするべきだったと後悔しています。
    • good
    • 0

この修正で最後にいたします。

いい加減なプログラム、そして連投、申し訳ありませんでした。

/*
prob2kai.c
*/

#include <stdio.h>

int main(int argc, char *argv[])
{
FILE *fp;
int moji, saigo, mojisu, gyosu;

if (argc != 2)
return 1;

if ((fp = fopen(argv[1], "r")) == NULL)
return 1;

for (mojisu = 0, gyosu = 0; (moji = fgetc(fp)) != EOF; mojisu++, saigo = moji) {
if (moji == '\n')
gyosu++;
}

fclose(fp);

if (saigo != '\n')
gyosu++;

printf("%d\t%d\t%s\n", mojisu, gyosu, argv[1]);

return 0;
}
「プログラミングC言語について次の問題がわ」の回答画像7
    • good
    • 0

forを抜けた後のprintfがよくないかもですね。



fclose(fp);

/* gyosuは改行を数えただけなので、ここで1を足す */
gyosu++;

printf("%d\t%d\t%s\n", mojisu, gyosu, argv[1]);
    • good
    • 0

私が適当に作ったプログラムです。



Ubuntu 20.04LTSで実行しましたが、回答はWindows 10でしていますので、タブや改行が¥になってしまっています。

/*
prob2.c

プログラミングC言語についてです
こちらの問題がわかりません
どなたか詳しい方、ご解答をお願いします。
実行時に main 関数の引数としてファイル名(つまり,文字列 1 つ)を受け取り,
与えられた名前のテキストファイルの
文字数・行数・ファイル名をタブ文字で区切って表示するプログラムを作成せよ.
実行時に与えるテキストファイルは,ASCII 文字のみからなるものとし,
実行ファイルと同じディレクトリに存在するものとする。

ヒント
行数 = 現れる改行文字の個数 + 1

実行例
$ cat testdata
book boots
cat dog horse
car bus train
$ ./prob2 14-2-data.txt
38 3 14-2-data.txt
*/
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
FILE *fp;
int moji, mojisu, gyosu;

if (argc != 2)
return 1;

if ((fp = fopen(argv[1], "r")) == NULL)
return 1;

for (mojisu = 0, gyosu = 0; (moji = fgetc(fp)) != EOF; mojisu++) {
if (moji == '\n') {
gyosu++;
printf("[%04x]\n", moji); /* デバッグ用 */
} else
printf("[%04x]", moji); /* デバッグ用 */
}
printf("\nここまでデバッグ表示\n"); /* デバッグ用 */

fclose(fp);

printf("%d\t%d\t%s\n", mojisu, gyosu + 1, argv[1]);

return 0;
}

テキストファイルは、最後の改行を削除したものを使っています。

テキストファイルをcatコマンドで表示したとき、終了後のプロンプト表示位置が問題文と異なってしまいます。

問題文と同じ結果にするには3行目の最後も改行を入れないといけませんが、そうしますと文字数が39になってしまいます。

内容に間違いがありましたら申し訳ありません。
「プログラミングC言語について次の問題がわ」の回答画像5
    • good
    • 0

私なりに試してみましたが、問題文がおかしいような気がします。



問題文を読みますと、テキストファイルの3行目の最後には改行はないと思うのですが、geditで作成しますと、改行しなくても保存時に改行が入ってしまいます。

バイナリエディタを使用して最後の改行を削除しますと、今度はcatコマンドで表示させたときに問題文のようになりません。
試しに作ったプログラムも適当に作りましたのできちんとテストしていませんが、問題文の印刷ミスではないでしょうか。

私が勘違いしていましたら申し訳ありません。
    • good
    • 0

あ, 確かに「実行例」がおかしいっすね>#2. というかその前の「問題」の文章もおかしいけど.



まず「文字」ってなんなのか, そしてそれをどう数えるのかがどこにも書いてない. UTF-32 で書かれたファイル突っ込まれたらどうするつもりなんだろう. そして「ヒント」もおかしい. その計算はどうして出てくるのか.
    • good
    • 0

実行例がおかしくない?



38 3 [引数]

って表示するだけのプログラムなら、mainで
printf("38\t3\t%s\n", argv[1]);
でいいんじゃね。
    • good
    • 1

何をどう考え, どこまでできていてどこで何にどう困っている?

    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

教えて!goo グレード

このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング