ファイル中から文字列の検索

ファイルから文字列を検索する例題です。

ファイル中から文字列の検索(list_4.c)
#include <stdio.h>

#define SCHSTR "hello"
#define std_in "<stdin>"

//-----------------------------------------------------------------
void usage(char* cmd);
void chop_crlf(char* buff);
char* search(char* text,char* key);
//-----------------------------------------------------------------

int main(int argc,char* argv[])
{
    FILE *fp;
    int i,count;
    char *cmd,*ifile=std_in,*schstr=SCHSTR,*p;
    char buf[512];
    //--------------------------------------------------
    // 引数の読込み
    //--------------------------------------------------
    cmd = argv[0];
    if(argc<2){ usage(cmd); return 0; }
    for(i=1;i<argc;i++){
        if(!strcmp(argv[i],"-s")){
            if(++i>=argc){ usage(cmd); return 0; }
            schstr = argv[i];
        } else ifile = argv[i];
    }
    printf("search string:%s\n",schstr);
    printf("   input file:%s\n",ifile);
    //--------------------------------------------------
    // ファイル入力
    //--------------------------------------------------
    if(strcmp(ifile,std_in)){
        if((fp=fopen(ifile,"r")) == NULL){
            fprintf(stderr,"No such file or directory.\n");
            return -1;
        }
    } else fp = stdin; // 標準入力より入力
    //--------------------------------------------------
    // 文字列の検索
    //--------------------------------------------------
    i=count=0;
    memset(buf,0,sizeof(char)*512);
    while(fgets(buf,512,fp)){
        chop_crlf(buf);
        p=search(buf,schstr);
        while(p!=NULL){
            count ++;
            printf("%d:%s:%s\n",i+1,p,buf);
            p=search(p+strlen(schstr),schstr);
        }
        i++;
        memset(buf,0,sizeof(char)*512);
    }
    fclose(fp);
    if(!count) printf("string not found\n");
    
    return 0;
}
//-----------------------------------------------------------------
// コマンドヘルプ
//-----------------------------------------------------------------
void usage(char* cmd)
{
    fprintf(stderr,"usage: %s file -s <search string>\n",cmd);
}
//-----------------------------------------------------------------
// 改行コードの除去
//-----------------------------------------------------------------
void chop_crlf(char* buff)
{
    int i,bufleng = strlen(buff);
    for(i=0;i<bufleng;i++){
        if(buff[i] == '\r') buff[i] = 0;
        if(buff[i] == '\n') buff[i] = 0;
    }
}
//-----------------------------------------------------------------
// 文字列の検索
//-----------------------------------------------------------------
char* search(char* text,char* key)
{
    int k,m,n;
    char *p;
    char skip[512];
    n=strlen(key); m=strlen(text);
    for(k=0;k<512;k++) skip[k]=n;
    for(k=0;k<n-1;k++) skip[key[k]]=n-1-k;
    p=text+n-1;
    while(p<text+m){
        if(*p==key[n-1]){           /* 右端の文字だけ比較 */
            if(strncmp(p-n+1,key,n)==0) /* キー全体を比較 */
                return (p-n+1);
        }
        p=p+skip[*p];               /* サーチ位置を進める */
    }
    return NULL;
}

検索対象ファイル(reidai.txt)
murakami pen pen
akitsugu murakami
c-gengo reidai
reidai program
text pen
pen

result
Gami[116]% list_4
usage: list_4 file -s <search string>
Gami[117]% list_4 reidai.txt
search string:hello
input file:reidai.txt
string not found
Gami[118]% list_4 reidai.txt -s murakami
search string:murakami
input file:reidai.txt
1:murakami pen pen:murakami pen pen
2:murakami:akitsugu murakami
Gami[119]% list_4 -s murakami  → 標準入力からの入力
search string:murakami
input file:<stdin>
a
b
c
d
murakami
5:murakami:murakami
pen
Gami[120]%
inserted by FC2 system