Memo

メモ > 技術 > プログラミング言語: C/C++ > C: Linuxでの基本的なプログラム

■C: Linuxでの基本的なプログラム
■コマンドライン引数の表示
$ vi args.c
#include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { int i; printf("argc=%d\n", argc); for (i = 0; i < argc; i++) { printf("argc[%d]=%s\n", i, argv[i]); } exit(0); }
$ gcc -o args args.c $ ./args argc=1 argc[0]=./args $ ./args x y z argc=4 argc[0]=./args argc[1]=x argc[2]=y argc[3]=z
■標準Cライブラリの場所
$ ls /lib64/libc.so.6 /lib64/libc.so.6 $ ls -l /lib64/libc.so.6 lrwxrwxrwx. 1 root root 12 12月 27 02:19 /lib64/libc.so.6 -> libc-2.17.so
■catコマンドを作る
$ vi cat.c
#include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { int i; for (i = 1; i < argc; i++) { FILE *f; int c; f = fopen(argv[i], "r"); if (!f) { perror(argv[i]); exit(1); } while ((c = fgetc(f)) != EOF) { if (putchar(c) < 0) exit(1); //if (fputc(c, stdout) < 0) exit(1); } fclose(f); } exit(0); }
$ gcc -o cat cat.c $ ./cat $ ./cat cat.c
■headコマンドを作る(処理対象は標準出力のみ)
$ vi head.c
#include <stdio.h> #include <stdlib.h> static void do_head(FILE *f, long nlines); int main(int argc, char *argv[]) { if (argc != 2) { fprintf(stderr, "Usage: %s n\n", argv[0]); exit(1); } do_head(stdin, atol(argv[1])); exit(0); } static void do_head(FILE *f, long nlines) { int c; if (nlines <= 0) return; while ((c = getc(f)) != EOF) { if (putchar(c) < 0) exit(1); if (c == '\n') { nlines--; if (nlines == 0) return; } } }
$ gcc -o head head.c $ ./head $ cat head.c | ./head 5
■headコマンドを作る(引数でファイルを指定)
$ vi head.c
#include <stdio.h> #include <stdlib.h> static void do_head(FILE *f, long nlines); int main(int argc, char *argv[]) { long nlines; if (argc < 2) { fprintf(stderr, "Usage: %s n [file file...]\n", argv[0]); exit(1); } nlines = atol(argv[1]); if (argc == 2) { do_head(stdin, atol(argv[1])); } else { int i; for (i = 2; i < argc; i++) { FILE *f; f = fopen(argv[i], "r"); if (!f) { perror(argv[i]); exit(1); } do_head(f, nlines); fclose(f); } } exit(0); } static void do_head(FILE *f, long nlines) { int c; if (nlines <= 0) return; while ((c = getc(f)) != EOF) { if (putchar(c) < 0) exit(1); if (c == '\n') { nlines--; if (nlines == 0) return; } } }
$ gcc -o head head.c $ ./head $ cat head.c | ./head 5 $ ./head 5 head.c
■headコマンドを作る(オプションを扱う)
$ vi head.c
#include <stdio.h> #include <stdlib.h> /* getopt_long() のプロトタイプ宣言を取り込む */ #define _GNU_SOURCE #include <getopt.h> static void do_head(FILE *f, long nlines); #define DEFAULT_N_LINES 10 /* ロングオプションの仕様を定義する */ static struct option longopts[] = { {"lines", required_argument, NULL, 'n'}, {"help", no_argument, NULL, 'h'}, {0, 0, 0, 0 } }; int main(int argc, char *argv[]) { int opt; long nlines; /* オプションを解析するループ */ while ((opt = getopt_long(argc, argv, "n:", longopts, NULL)) != -1) { switch (opt) { case 'n': nlines = atol(optarg); break; case 'h': fprintf(stdout, "Usage: %s [-n LINES] [FILE ...]\n", argv[0]); exit(0); case '?': fprintf(stderr, "Usage: %s [-n LINES] [FILE ...]\n", argv[0]); exit(1); } } /* * optind は現在処理中のオプションのargvでのインデックスが入るグローバル変数 * この場合、オプションではない最初の引数のインデックスを指している */ if (optind == argc) { do_head(stdin, nlines); } else { int i; for (i = optind; i < argc; i++) { FILE *f; f = fopen(argv[i], "r"); if (!f) { perror(argv[i]); exit(1); } do_head(f, nlines); fclose(f); } } exit(0); } static void do_head(FILE *f, long nlines) { int c; if (nlines <= 0) return; while ((c = getc(f)) != EOF) { if (putchar(c) < 0) exit(1); if (c == '\n') { nlines--; if (nlines == 0) return; } } }
$ gcc -o head head.c $ ./head -n 5 head.c $ cat head.c | ./head -n 5
■grepコマンドを作る
$ vi grep.c
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <regex.h> static void do_grep(FILE *f, regex_t *pat); int main(int argc, char *argv[]) { regex_t pat; int err; if (argc < 2) { fputs("no pattern\n", stderr); exit(1); } /* 文字列で表現されている正規表現パターンを、専用のデータ型(regex_t)に変換する */ err = regcomp(&pat, argv[1], REG_EXTENDED | REG_NOSUB | REG_NEWLINE); if (err != 0) { char buf[1024]; /* regcomp() のエラーコードをエラーメッセージに変換する */ regerror(err, &pat, buf, sizeof buf); puts(buf); exit(1); } if (argc == 2) { do_grep(stdin, &pat); } else { int i; for (i = 2; i < argc; i++) { FILE *f; f = fopen(argv[i], "r"); if (!f) { perror(argv[i]); exit(1); } do_grep(f, &pat); fclose(f); } } /* regcomp() で確保したメモリを開放する */ regfree(&pat); exit(0); } static void do_grep(FILE *f, regex_t *pat) { char buf[4096]; /* 正規表現に適合するか調べるために、バイト単位ではなく行単位で読み込む */ while (fgets(buf, sizeof buf, f)) { /* 正規表現に適合する行のみを出力する */ if (regexec(pat, buf, 0, NULL, 0) == 0) { fputs(buf, stdout); } } }
$ gcc -o grep grep.c $ ./grep pat grep.c
■lsコマンドを作る
$ vi ls.c
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <dirent.h> static void do_ls(char *path); int main(int argc, char *argv[]) { int i; if (argc < 2) { fprintf(stderr, "%s: no arguments\n", argv[0]); exit(1); } for (i = 1; i < argc; i++) { do_ls(argv[1]); } exit(0); } static void do_ls(char *path) { DIR *d; struct dirent *ent; d = opendir(path); if (!d) { perror(path); exit(1); } while (ent =readdir(d)) { printf("%s\n", ent->d_name); } closedir(d); }
$ gcc -o ls ls.c $ ./ls .
■mkdirコマンドを作る
$ vi mkdir.c
#include <stdio.h> #include <stdlib.h> #include <sys/stat.h> #include <sys/types.h> int main(int argc, char *argv[]) { int i; if (argc < 2) { fprintf(stderr, "%s: no arguments\n", argv[0]); exit(1); } for (i = 1; i < argc; i++) { if (mkdir(argv[i], 0777) < 0) { perror(argv[i]); exit(1); } } exit(0); }
$ gcc -o mkdir mkdir.c $ ./mkdir test
■rmdirコマンドを作る
$ vi mkdir.c
#include <stdio.h> #include <stdlib.h> #include <unistd.h> int main(int argc, char *argv[]) { int i; if (argc < 2) { fprintf(stderr, "%s: no arguments\n", argv[0]); exit(1); } for (i = 1; i < argc; i++) { if (rmdir(argv[i]) < 0) { perror(argv[i]); exit(1); } } exit(0); }
$ gcc -o rmdir rmdir.c $ ./rmdir test
■unlinkコマンドを作る
$ vi mkdir.c
#include <stdio.h> #include <stdlib.h> #include <unistd.h> int main(int argc, char *argv[]) { int i; if (argc < 2) { fprintf(stderr, "%s: no arguments\n", argv[0]); exit(1); } for (i = 1; i < argc; i++) { if (unlink(argv[i]) < 0) { perror(argv[i]); exit(1); } } exit(0); }
$ gcc -o unlink unlink.c $ ./unlink test.txt
■mvコマンドを作る
$ vi mv.c
#include <stdio.h> #include <stdlib.h> #include <unistd.h> int main(int argc, char *argv[]) { int i; if (argc != 3) { fprintf(stderr, "%s: wrong arguments\n", argv[0]); exit(1); } if (rename(argv[1], argv[2]) < 0) { perror(argv[1]); exit(1); } exit(0); }
$ gcc -o mv mv.c $ ./mv test1.txt test2.txt

Advertisement