ページ 11

指定した文字列をテキストファイルから検索→表示するプログラム

Posted: 2019年5月23日(木) 16:42
by waka
初めまして。
C言語初心者です。
現在、課題で
『指定された文字列をファイル内から検索し、見つかった行をコンソールに表示する』
というプログラムを作成中です。
自分なりに調べ簡単なコードで出来たと思ったのですが
【検索文字列は『プログラムの引数』にする事】
【何度でも検索→表示ができる事】
という条件を追加されました。
意味が分からず手が止まってしまい、進めません。

読み込むファイルはテキストファイル、ツールはVisual Studio 2017 です。

現時点のソースを載せますので、良ければどなたかご教授願います。
出来ればソースを書いて頂けると嬉しいです。宜しくお願い致します。

コード:

#include "pch.h"
#include <iostream>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#pragma warning(disable : 4996)

#define BIT_SIZE 256 // バイトサイズ
#define KEY_SIZE 100 // 検索文字数

int main(void)
{
	FILE *fp; // ファイルポインタ
	int line = 1; // 読み込んだ行数
	char    path[100]; // 入力ファイルのパス
	char buf[BIT_SIZE]; // サイズ
	char key[KEY_SIZE + 1]; // 検索文字列
	//static const char FILE_NAME[] = "D:test.txt"; // ファイル名

	printf("検索するファイル名を入力せよ→");
	scanf("%s%*c", path);

	if ((fp = fopen(path,"r")) == NULL)
	{
		printf("Error: %s このファイルは開けない。\n", path);
		return 1;
	}

	printf("検索する文字列を入力せよ→");
	scanf("%s", key);

	while (fgets(buf, sizeof(buf), fp) != NULL)
	{
		if (strstr(buf, key) != NULL)
		{
			printf("%d行目: %s", line, buf);
		}
		line++;
	}
	fclose(fp);

	return 0;
}
[code]

Re: 指定した文字列をテキストファイルから検索→表示するプログラム

Posted: 2019年5月23日(木) 18:26
by waka
どうやら
【検索文字列は『プログラムの引数』にする事】
というのは コマンドライン引数 を使用するみたいなのですが、うまくいきません。
宜しくお願い致します。

Re: 指定した文字列をテキストファイルから検索→表示するプログラム

Posted: 2019年5月26日(日) 08:59
by あたっしゅ
「プログラムの引数」を検索すれば

http://www.ritsumei.ac.jp/~mmr14135/johoWeb/cmnds.html
コマンドライン引数(ja)

と出てきます。

Re: 指定した文字列をテキストファイルから検索→表示するプログラム

Posted: 2019年5月26日(日) 09:02
by かずま
waka さんが書きました:
5ヶ月前
【検索文字列は『プログラムの引数』にする事】
というのは コマンドライン引数 を使用するみたいなのですが、うまくいきません。
検索文字列を実行時に入力

コード:

#include <stdio.h>

int main(void)
{
	char key[100];

	printf("検索する文字列を入力せよ→");
	scanf("%99s", key);
	printf("検索文字列: %s\n", key);
	return 0;
}
検索文字列をコマンドライン引数にする

コード:

#include <stdio.h>

int main(int argc, char *argv[])
{
	if (argc != 2) {
		printf("usage: %s key\n", argv[0]);
		return 1;
	}
	printf("検索文字列: %s\n", arg[1]);
	return 0;
}
ひょっとして、Visual Studio 2017 でコマンドライン引数を
指定する方法が分からないのですか?
ソリューションエクスプローラーを開いて、プロジェクト名を右クリックし、
一番下のプロパティを選択すると、プロジェクトプロパティが開きます。
構成プロパティでデバッグを選択し、コマンド引数に文字列を入れます。

Visual Studio を使わずコマンドプロンプトからプログラムを実行するなら、
スタートボタンで Visual Studio 017 のフォルダを開き、
Developer Command Prompt for VS 2017 を起動してください。

Re: 指定した文字列をテキストファイルから検索→表示するプログラム

Posted: 2019年5月27日(月) 10:55
by かずま
かずま さんが書きました:
5ヶ月前

コード:

	printf("検索文字列: %s\n", arg[1]);
すみません。arg[1] は argv[1] の間違いです。

元のプログラムについて、気になったことを述べます。

・「#include "pch.h"」pch.h の正体が分かりません。
・「#include <iostream>」これは C ではなく C++ のヘッダです。
 wakaさんは「C言語初心者です」と言っているので変です。エラーにならない
 のはソースファイルの拡張子を .c にしていないからではありませんか?
・「#include <stdlib.h>」不要だと思います。
・「#define BIT_SIZE 256 // バイトトサイズ」BUF_SIZE でしょう。
・「int line = 1; // 読み込んだ行数」まだ読み込んでいないのに 1?
 int line = 0; にして、fgets の直後に line++: としたほうがよいのでは?
・「scanf("%s%*c", path);」%*c は不要です。
・「[ code]」codeタグの終了には / をつけて [/code] にします。

さて、【何度でも検索→表示ができる事】の件ですが、検索文字列を
コマンドライン引数で指定するということは、ファイル名を何度でも
入力して検索表示を繰り返すということではありませんか?

コード:

#include <stdio.h>   // fopen, fclose, fgets, printf
#include <string.h>  // strstr

#pragma warning(disable : 4996)

#define BUF_SIZE 256 // 入力行バッファサイズ
#define KEY_SIZE 100 // 検索文字列の最大文字数

int main(int argc, char *argv[])
{
	FILE *fp; // ファイルポインタ
	int line = 0; // 読み込んだ行数
	char path[100]; // 入力ファイルのパス
	char buf[BUF_SIZE]; // 入力行バッファ
	char key[KEY_SIZE + 1]; // 検索文字列

	if (argc != 2) {
		printf("使用方法: %s key\n", argv[0]);
		return 1;
	}
	while (1) {
		printf("検索するファイル名を入力せよ(終了は .)→");
		if (scanf("%s", path) != 1 || path[0] == '.') break;
		fp = fopen(path, "r");
		if (fp == NULL) {
			printf("Error: %s このファイルは開けない。\n", path);
			return 1;
		}
		while (fgets(buf, sizeof(buf), fp) != NULL) {
			line++;
			if (strstr(buf, argv[1]) != NULL)
				printf("%d行目: %s", line, buf);
		}
		fclose(fp);
	}
	return 0;
}

Re: 指定した文字列をテキストファイルから検索→表示するプログラム

Posted: 2019年5月27日(月) 11:06
by かずま
かずま さんが書きました:
5ヶ月前

コード:

#define KEY_SIZE 100 // 検索文字列の最大文字数

	char key[KEY_SIZE + 1]; // 検索文字列
すみません。この 2行は不要でした。
key の代わりに argv[1] を使いますから。

Re: 指定した文字列をテキストファイルから検索→表示するプログラム

Posted: 2019年5月27日(月) 18:53
by waka
ご返信いただきありがとうございます!
こちらの課題は何とか出来ました。

>Visual Studio 2017 でコマンドライン引数を
指定する方法が分からないのですか?

そこは分かっていたのですが、
int main(int argc, char *argv[]
の使い方?が分からなかったので混乱していました。

また、色々とご指摘いただき有難うございました。

C言語の研修を開始したばかりですが、初めから
Visual Studio 2017の
新規作成→プロジェクト→Visual C++→Windows コンソール アプリケーション
でソースを書くように指導されましてそのまま使っています。

テキストや他の方の書かれたソースを組み合わせながら書いている部分も多いため、
自分のレベルと合っていないみたいです…
もっと勉強します。
丁寧に回答して下さって本当にありがとうございました。