C言語でgrepコマンドを書きたい

■要求定義
– 指定した文字列がテキスト内に存在した場合、その行を抽出する

e.g.
sample.txt

Aries
Taurus
Gemini
Cancer
Leo
Virgo
Libra
Scorpio
Sagittarius
Capricorn
Aquarius
Pisces

$ grep -n Leo sample.txt // オプションの-nは行数
5:Leo
$ grep -c Leo sample.txt // オプションの-cは回数
1
$ grep Cancer ./*
./sample.txt:Cancer

■検討事項
– 正規表現で、検索文字と完全一致する文字が含まれていれば、ファイル名を返す(return 0)として、含まれていなければreturn 1とするで良いか。

strchrで先頭が一致するアドレスをポインタで返す

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

int main(void){

	char str[] = "100-0005";
	char *adr1, *adr2;

	adr1 = strchr(str, (int)'-'); //文字列 str の先頭から'-'を探し、最初に見つかった位置をポインタで返却
	printf("result1: %s\n", adr1);

	adr2 = strchr(str, (int)'x'); 
	printf("result2: %s\n", adr2);

	return 0;
}

$ ./dev
result1: -0005
result2: (null)

文字列の一致にはstrstrを使用する。

int main(void){

	char str[] = "〒100-0005 東京都千代田区丸の内一丁目";
	char *adr1, *adr2;

	adr1 = strstr(str, "千代田区"); //文字列strの中から文字列を探しそのアドレスを返す
	printf("result1: %s\n", adr1);

	adr2 = strstr(str, "港区"); 
	printf("result2: %s\n", adr2);

	return 0;
}

$ ./dev
result1: 千代田区丸の内一丁目
result2: (null)

### 正規表現を使った方法
– ヘッダーファイル「regex.h」をインクルード
– 正規表現を使った検索を行うには、正規表現のオブジェクトを格納するregex_t型の構造体と、正規表現にマッチしたインデックスを格納するregmatch_t型の構造体の配列が必要
– regcomp():正規表現コンパイル, regexec():正規表現による検索実行, regfree():regex_t型のオブジェクトのメモリ解放 を使用する

int regcomp(regex_t *preg, const char *regex, int cflags)
int regexec(const regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags)

#include 
#include 

int main(void){

	char str[] = "〒100-0005 東京都千代田区丸の内一丁目";
	regex_t preg; // 正規表現のオブジェクト
	size_t num = 5;
	regmatch_t pmatch[num]; // 正規表現にマッチしたインデックスを格納

	const char pattern[] = "〒([0-9]{3})-([0-9]{4})(.+)";

	// 正規表現のコンパイル
	if (regcomp(&preg, pattern, REG_EXTENDED|REG_NEWLINE) != 0){
		printf("failed\n");
		return -1;
	}

	// 入力文字列の出力
	printf("input char is: %s\n", str);

	// 正規表現による検索
	if(regexec(&preg, str, num, pmatch, 0) != 0){
		printf("does not matched\n");
	} else {
		for (int i = 0; i < num; i++){
			if(pmatch[i].rm_so >= 0 && pmatch[i].rm_eo >= 0){
				printf("matched index is %d~%d, str: ", (int)pmatch[i].rm_so, (int)pmatch[i].rm_eo);
				for (int j = pmatch[i].rm_so ; j < pmatch[i].rm_eo; j++){
					putchar(str[j]);
				}
			}
			printf("\n");
		}
	}

	// オブジェクトのメモリ開放
	regfree(&preg);

	return 0;
}