実現したいこと
オプションを取るgrep関数内の、argcとargvの扱い方について理解する
前提
下記オプションを取れるgrep関数を実現するソースコード上にて、argcとargvを加算、減算するタイミングとその目的が理解できない状態です。
「該当のソースコード」欄に、ソースコードの全文を掲載させて頂きました。
この中で、以下の4行について、なぜargcとargvをここで加算、減算しているのかを教えて頂きたく思います。
/*get_opt関数直後の2文*/ argc -= optind; argv += optind; /*char *pattern = argv[0]を実行した直後の2文*/ argc--; argv++;
get_opt関数直後の2文については、以下のような理解です。
・ argc += optindについて
→grepしたい文字列が引数としてコマンド実行時に与えられているかを判定するため
・argv += optindについて
→grepしたい文字列を*charに格納するため、argvの先頭アドレス + optindバイト分argv[0]のアドレスをずらしている
問題は、char *pattern = argv[0]を実行した直後の2文です。
ここでなぜ、argc --; argv ++;が挟まるのでしょうか?
(この処理を挟むことで、コードが正常に実行されることは分かるのですが、タイミングと目的が分からず)
よろしくお願い致します。
該当のソースコード
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <regex.h> #include <unistd.h> static void grep_file(regex_t *re, char *path); static void grep_stream(regex_t *re, FILE *f); static int opt_invert = 0; static int opt_ignorecase = 0; int main(int argc, char *argv[]) { int opt; while ((opt = getopt(argc, argv, "iv")) != -1) { switch (opt) { case 'i': opt_ignorecase = 1; break; case 'v': opt_invert = 1; break; case '?': fprintf(stderr, "Usage: %s [-iv] [<file>...]\n", argv[0]); exit(1); } } argc -= optind; argv += optind; if (argc < 1) { fputs("no pattern\n", stderr); exit(1); } char *pattern = argv[0]; argc--; argv++; int re_mode = REG_EXTENDED | REG_NOSUB | REG_NEWLINE; if (opt_ignorecase) re_mode |= REG_ICASE; regex_t re; int err = regcomp(&re, pattern, re_mode); if (err != 0) { char buf[1024]; regerror(err, &re, buf, sizeof buf); puts(buf); exit(1); } if (argc == 0) { grep_stream(&re, stdin); } else { int i; for (i = 0; i < argc; i++) { grep_file(&re, argv[i]); } } regfree(&re); exit(0); } static void grep_file(regex_t *re, char *path) { FILE *f; f = fopen(path, "r"); if (!f) { perror(path); exit(1); } grep_stream(re, f); fclose(f); } static void grep_stream(regex_t *re, FILE *f) { char buf[4096]; int matched; while (fgets(buf, sizeof buf, f)) { matched = (regexec(re, buf, 0, NULL, 0) == 0); if (opt_invert) { matched = !matched; } if (matched) { fputs(buf, stdout); } } }
回答1件
あなたの回答
tips
プレビュー