読者です 読者をやめる 読者になる 読者になる

grepもどき(正規表現非対応)

学校の課題で作ったプログラムをさらしてみます!
grepもどき(正規表現・ファイル名ワイルドカード非対応)をつくる

  • Cでかく
  • strstr使用禁止
  • -vオプションをつけると出力反転
  • -iオプションをつけると大文字小文字無視
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

#define MAX_TEXT 300
#define TRUE 1
#define FALSE 0

typedef int BOOL;


void usage(void)
{
    printf("Usage: search [-hiv] PATTERN FILE1, [FILE2 ...]\n");
    printf("-h    Output usage\n");
    printf("-i    Ignore case\n");
    printf("-v    Invert matching\n");
    exit(0);
}

void strUpper(char* s)
{
    char* pc = s;
    for (; *pc != '\0' ; pc++)
        *pc = toupper(*pc);
}


void checkArgc(const int argc)
{
    if(argc < 1){
        printf("Bad arguments\n\n");
        usage();
    }
}

BOOL isMatch(const char* s1, const char* s2)
{
    int i;
    for(i=0; s2[i] != '\0'; i++) {
        if (*s1=='\0' && s2[i] != '\0')
            return FALSE;
        if (*s1 != s2[i])
            i=0;
        s1++;
    }
    return TRUE;
}


int main(int argc, char* argv[])
{
    BOOL ignoreCase = FALSE;
    BOOL invertMatch = FALSE;
    
    argv++;
    argc--;
    while(argc >= 1 && argv[0][0] == '-'){
        switch(argv[0][1]){
          case 'h':
            usage();
          case 'i':
            ignoreCase = TRUE;
            break;
          case 'v':
            invertMatch = TRUE;
            break;
          default :
            printf("Bad option\n");
            usage();
        }
        argv++;
        argc--;
    }

    checkArgc(argc);

    char* pattern = argv[0];
    argv++;
    argc--;
    if(ignoreCase)
        strUpper(pattern);

    checkArgc(argc);

    while(argc >= 1){
        FILE* fp = fopen(argv[0], "r");
        char text[MAX_TEXT];
        
        if (fp == NULL){
            printf("file '%s' cannnot open.\n", argv[0]);
            exit(0);
        }

        while(fgets(text, MAX_TEXT, fp)){
            BOOL m;
            if(ignoreCase){
                char ignoreCaseText[MAX_TEXT];
                strcpy(ignoreCaseText, text);
                strUpper(ignoreCaseText);
                m = isMatch(ignoreCaseText, pattern);
            }else{
                m = isMatch(text, pattern);
            }
            
            if((m && !invertMatch) || (!m && invertMatch))
                printf("%s: %s", argv[0], text);
        }
        argv++;
        argc--;
    }
    
    return 0;
}


1コマで何も考えずにゴリゴリかいたから、こんなもんじゃないですかね。でもmainがクソながいです。

途中で気づいたこと: C99にはboolがある
友達に突っ込まれたこと: getopt使えよ