· KLDP.org · KLDP.net · KLDP Wiki · KLDP BBS ·
Devel FilterCSkeleton

Skeleton Filter Program in C

ÀÌ ±ÛÀº C ¾ð¾î¸¦ ½á¼­ DevelFilterSkeleon¿¡¼­ ´Ù·é ÇÊÅÍ ÇÁ·Î±×·¥ÀÇ »©´ë¸¦ ¸¸µå´Â ¹æ¹ýÀ» ¼Ò°³ÇÕ´Ï´Ù.


1.1. Output Messages

ÇÊÅÍ ÇÁ·Î±×·¥Àº ¾î¶² »óȲÀÌ ¹ß»ýÇßÀ» ¶§, »ç¿ëÀÚ¿¡°Ô º¸°íÇϰųª, ¿¡·¯¸¦ Ãâ·ÂÇÒ ¶§°¡ Á¾Á¾ ¹ß»ýÇϱ⠶§¹®¿¡, °æ°í ¶Ç´Â ¿¡·¯ ¸Þ½ÃÁö¸¦ ³» º¸³»´Â °æ¿ì°¡ ÀÖ½À´Ï´Ù. ÇÊÅÍ ÇÁ·Î±×·¥Àº ±âº»ÀûÀ¸·Î ó¸®ÇÑ µ¥ÀÌÅ͸¦ Ç¥ÁØ Ãâ·ÂÀ» ÅëÇØ ³» º¸³»¹Ç·Î, ÀÌ·± ¸Þ½ÃÁöµéÀ» Ç¥ÁØ ÀÔ·ÂÀ¸·Î º¸³½´Ù¸é, µ¥ÀÌÅÍ¿Í ¼¯ÀÏ °æ¿ì°¡ Àֱ⠶§¹®¿¡ ´ëºÎºÐ Ç¥ÁØ Ãâ·ÂÀ» ½á¼­ ¸Þ½ÃÁö¸¦ Ãâ·ÂÇÕ´Ï´Ù.

´ë°³ ÇÊÅÍ ÇÁ·Î±×·¥ÀÌ µû·Î Ãâ·ÂÇÏ´Â ¸Þ½ÃÁö´Â ÁÖ·Î °æ°í¼ºÀ̳ª, ¿¡·¯°¡ ¹ß»ýÇÑ °æ¿ì°¡ ´ëºÎºÐÀÔ´Ï´Ù. ¸¸¾à ½Ã½ºÅÛ ÇÔ¼ö¸¦ È£ÃâÇؼ­ ¿¡·¯°¡ ¹ß»ýÇÑ °æ¿ì¿¡´Â Àü¿ª º¯¼ö errno¿¡ ¿¡·¯ ¿øÀÎÀÌ ÀúÀåµÇ°Ô µÇ´Âµ¥ (¸ðµç ½Ã½ºÅÛ ÇÔ¼öµéÀÌ errno¸¦ ¾²´Â °ÍÀº ¾Æ´Õ´Ï´Ù.), ÀÌ °æ¿ì strerror(3)¸¦ ½á¼­, ¿øÇÏ´Â ¿¡·¯ ¸Þ½ÃÁö¸¦ ¾òÀ» ¼ö ÀÖ½À´Ï´Ù.

¿¡·¯¸¦ ½±°Ô ó¸®Çϱâ À§ÇØ ¿ì¸®´Â GNU È®Àå ÇÔ¼öÀÎ error(3)¸¦ ¾µ °ÍÀÔ´Ï´Ù.

#include <error.h>

void error(int STATUS, int ERRNUM, const char *FORMAT, ...);

»ç¿ë¹ýÀº °£´ÜÇÕ´Ï´Ù. ¸ÕÀú, FORMAT°ú ±× ´ÙÀ½¿¡ µé¾î¿À´Â printf(3) ½ºÅ¸ÀÏ ÀÎÀÚ¸¦ ó¸®Çؼ­ Ç¥ÁØ ¿¡·¯·Î Ãâ·ÂÇÕ´Ï´Ù. ±×¸®°í ERRNUMÀÌ 0ÀÌ ¾Æ´Ñ °æ¿ì, error(3)´Â strerror(ERRNUM)À» ºÒ·¯¼­ ¸Þ½ÃÁö¸¦ Ç¥ÁØ ¿¡·¯·Î Ãâ·ÂÇÕ´Ï´Ù. ±× ´ÙÀ½, STATUS°¡ 0ÀÌ ¾Æ´Ñ °æ¿ì exit(STATUS)¸¦ È£ÃâÇØ ÁÝ´Ï´Ù.

¿¹¸¦ µé¾î Á¦ÀÛÇÒ ÇÊÅÍ ÇÁ·Î±×·¥ÀÌ ÁöÁ¤ÇÑ ¼³Á¤ ÆÄÀÏ¿¡¼­ ¿øÇÏ´Â ¼³Á¤À» ÀоîµéÀÎ´Ù°í °¡Á¤ÇØ º¾½Ã´Ù. ÀÌ ¼³Á¤ ÆÄÀÏ À̸§Àº INIT_FILEÀ̶õ ¸ÅÅ©·Î¿¡ ÀúÀåÀÌ µÇ¾î ÀÖ°í, À̸¦ fopen(3)À¸·Î ¿­ ¶§, ¿¡·¯°¡ ¹ß»ýÇß´Ù°í °¡Á¤ÇսôÙ. ¶Ç, ÀÌ ÇÊÅÍ ÇÁ·Î±×·¥Àº ÁöÁ¤ÇÑ ¼³Á¤ ÆÄÀÏÀÌ Á¸ÀçÇÏÁö ¾Ê´Â °æ¿ì, °æ°í ¸Þ½ÃÁö¸¦ Ãâ·ÂÇÏ°í, ±âº» °ªÀ» ½á¼­ µ¿ÀÛÇÑ´Ù°í °¡Á¤ÇսôÙ. ÀÌ °æ¿ì ¿ì¸®´Â ´ÙÀ½°ú °°Àº Äڵ带 ¸¸µé¾î¾ß ÇÕ´Ï´Ù:

FILE *fp;
fp = fopen(INIT_FILE, "r");
if (!fp) {
  error(0, errno, "cannot open %s", INIT_FILE);
}

±×·¯¸é ³ªÁß¿¡ ÀÌ ÇÁ·Î±×·¥À» ½ÇÇàÇÒ ¶§ (ÇÁ·Î±×·¥ À̸§Àº "foo"¶ó°í °¡Á¤ÇսôÙ), INIT_FILEÀÌ ¾ø´Â °æ¿ì, ´ÙÀ½°ú °°ÀÌ °æ°í ¸Þ½ÃÁö°¡ Ãâ·ÂµÇ´Â °ÍÀ» ¾Ë ¼ö ÀÖ½À´Ï´Ù:

$ foo
foo: cannot open /etc/foorc: No such file or directory
$ _


1.2. Option Processing

°¡Àå ¸ÕÀú ó¸®ÇØ¾ß ÇÒ °ÍÀº command-line argument¸¦ ¹Þ¾Æ¼­ ó¸®ÇÏ´Â °ÍÀÔ´Ï´Ù. ÀÌ´Â main() ÇÔ¼ö¸¦, µÎ °³ÀÇ ÆĶó¸ÞÅ͸¦ ¹Þ¾Æ¼­ ó¸®ÇÏ°Ô ÇÒ ¼ö ÀÖ½À´Ï´Ù:

#include <stdio.h>

int
main(int argc, char *argv[])
{
  int i;
  for (int i = 0; i < argc; i++)
    printf("argv[%d]: %s\n", i, argv[i]);
  return 0;
}

À§ ¼Ò½º¸¦ ÄÄÆÄÀÏÇÏ°í ½ÇÇàÇØ º¸¸é argc¿Í argv°¡ ¾î¶°ÇÑ ¿ªÇÒÀ» ÇÏ´ÂÁö ½±°Ô ¾Ë ¼ö ÀÖ½À´Ï´Ù:

$ cc -Wall arg.c
$ ./a.out               # argc == 1
argv[0]: ./a.out
$ ./a.out hello world   # argc == 3
argv[0]: ./a.out
argv[1]: hello
argv[2]: world
$ ls *.c
arg.c  hello.c
$ ./a.out *.c           # argc == # of .c files plus 1.
argv[0]: ./a.out
argv[1]: arg.c
argv[2]: hello.c
$ _

¿É¼ÇÀ» ó¸®Çϱâ À§Çؼ­ getopt(3)À̳ª getopt_long(3) ÇÔ¼ö¸¦ ¾²´Â °ÍÀÌ Æí¸®ÇÕ´Ï´Ù. ¸ÕÀú °¡Àå ÈçÇÑ '-h'¿Í '-v' (µµ¿ò¸»°ú ¹öÀü Ãâ·Â) ¿É¼ÇÀ» ¸¸µé¾î º¾½Ã´Ù.

getopt(3)¿Í getopt_long(3)Àº ¿É¼Ç 󸮸¦ ¸Å¿ì °£´ÜÇÏ°Ô ÇØ ÁÝ´Ï´Ù. ¸ÕÀú ´ëºÎºÐ UNIX ½Ã½ºÅÛÀº POSIX.2¿¡ ÁØÇÏ´Â getopt(3)¸¦ Á¦°øÇϸç, GNU ½Ã½ºÅÛ¿¡¼­´Â È®Àå ÇÔ¼öÀÎ getopt_long(3)À» ¾µ ¼ö ÀÖ½À´Ï´Ù. getopt(3)°¡ ÇÑ ±ÛÀÚ ¿É¼Ç¸¸À» ó¸®ÇÒ ¼ö ÀÖ´Â ¹Ý¸é, getopt_long(3)Àº ÇÑ ±ÛÀÚ ¿É¼Ç »Ó¸¸ ¾Æ´Ï¶ó ±ä ¿É¼Çµµ ó¸® °¡´ÉÇÕ´Ï´Ù:

#include <unistd.h>

int getopt(int ARGC, char * const ARGV[], const char *OPTSTRING);

extern char *optarg;
extern int optind, opterr, optopt;

#include <getopt.h>

int getopt_long(int ARGC, char * const ARGV[], const char *OPTSTRING,
                const struct option *LONGOPTS, int *LONGINDEX);

¸ÕÀú µÎ ÇÔ¼öÀÇ ¼¼¹ø° ÆĶó¸ÞÅÍÀÎ OPTSTRING¿¡ ´ëÇØ ¾Ë¾Æ º¾½Ã´Ù. ÀÌ ÆĶó¸ÞÅÍ¿¡´Â, ÀÌ ÇÁ·Î±×·¥ÀÌ Ã³¸®ÇÒ ¼ö ÀÖ´Â ÇÑ ±ÛÀÚ ¿É¼ÇµéÀÇ ¸ñ·ÏÀ» ½á ÁÝ´Ï´Ù. ¸¸¾à ¿É¼ÇÀÌ ÀÎÀÚ¸¦ ¹Þ´Â´Ù¸é ¿É¼Ç ±ÛÀÚ µÚ¿¡ ':'µµ ½á ÁÝ´Ï´Ù. ¸¸¾à ¿É¼Ç¿¡ ´ëÇÑ ÀÎÀÚ¸¦ »ý·«ÇÒ ¼ö ÀÖ´Â °æ¿ì¿¡´Â ':'¸¦ µÎ°³ ½á ÁÝ´Ï´Ù. ¿¹¸¦ µé¾î ÇÁ·Î±×·¥ÀÌ Ã³¸®ÇÏ´Â ¿É¼ÇÀÌ '-h', '-v', '-q', '-o FILE' ÀÌ ³×°³¶ó°í Çϸé, OPTSTRINGÀº "hvqo:"°¡ µË´Ï´Ù.

ÀÌÁ¦ getopt(3)ÀÇ ¸®ÅÏ °ª¿¡ ´ëÇØ ¾Ë¾Æº¾½Ã´Ù. getopt(3)Àº ÇÁ·Î±×·¥¿¡ Àü´ÞµÈ ÀÎÀÚ¸¦ Çϳª¾¿ ó¸®ÇÕ´Ï´Ù. Áï, °³¹ßÀÚ´Â getopt(3)À» ÇÊ¿äÇÑ ¸¸Å­ ºÒ·¯¼­, ÇÁ·Î±×·¥¿¡ Àü´ÞµÈ ¿É¼ÇÀ» ¸ðµÎ ó¸®ÇØ ÁÖ¾î¾ß ÇÕ´Ï´Ù. ´õ ÀÌ»ó ó¸®ÇÒ ¿É¼ÇÀÌ ¾ø´Â °æ¿ì, getopt(3)´Â -1À» ¸®ÅÏÇÕ´Ï´Ù. µû¶ó¼­ ¿ì¸®´Â ´ÙÀ½°ú °°Àº Äڵ带 »ý°¢ÇÒ ¼ö ÀÖ½À´Ï´Ù:

int
main(int argc, char *argv[])
{
  int ch;

  while ((ch = getopt(argc, argv, "hvqo:")) != -1) {
    ...
  }
  ...
}

getopt(3)´Â ÀÚ½ÅÀÌ Ã³¸®ÇÑ ¿É¼Ç ±ÛÀÚ¸¦ ¸®ÅÏÇØ ÁÝ´Ï´Ù. µû¶ó¼­ getopt(3)°¡ '-h'¸¦ ó¸®Çß´Ù¸é 'h'¸¦ ¸®ÅÏÇÕ´Ï´Ù. µû¶ó¼­ ¿ì¸®´Â getopt(3)ÀÇ °á°ú¸¦ switch ¹®ÀåÀ» ½á¼­ ¿øÇÏ´Â ÀÛ¾÷À» ó¸®ÇØÁÖ¸é µË´Ï´Ù. ¸¸¾à ÇÁ·Î±×·¥ »ç¿ëÀÚ°¡ ¾Ë ¼ö ¾ø´Â ¿É¼ÇÀ» ½è´Ù¸é getopt(3)´Â '?'¸¦ ¸®ÅÏÇÕ´Ï´Ù. µû¶ó¼­ À§ ¿¹Á¦ÀÇ while ¹®Àå ¾ÈÀº ´ÙÀ½°ú °°ÀÌ ¾µ ¼ö ÀÖ½À´Ï´Ù:

switch (ch) {
case 'h':
  /* show help message and exit */
case 'v':
  /* show version information and exit */
case 'q':
  /* set quiet mode */
  break;
case 'o':
  /* set the output file name */
  break;
case '?':
  /* unknown option. ignored. */
  break;
default:
  /* getopt(3) returns unrecognized value. */
  abort();
}
¸ÕÀú getopt(3)°¡ '?'¸¦ ¸®ÅÏÇß´Ù¸é, ÇÁ·Î±×·¥ »ç¿ëÀÚ°¡ ¾Ë ¼ö ¾ø´Â ¿É¼ÇÀ» ÁöÁ¤ÇÑ °ÍÀ» ¶æÇÕ´Ï´Ù. ÀÌ °æ¿ì getopt(3)´Â ÀÚµ¿À¸·Î ¾Ë ¼ö ¾ø´Â ¿É¼ÇÀÌ µé¾î¿Ô´Ù´Â ¿¡·¯ ¸Þ½ÃÁö¸¦ Ãâ·ÂÇÕ´Ï´Ù¸¸, ÀÌ °ÍÀ¸·Î ÃæºÐÇÏÁö ¾Ê½À´Ï´Ù. ¿ì¸®´Â ÀÌ °æ¿ì '-h'¸¦ ¾²¸é µµ¿ò¸»À» º¼ ¼ö ÀÖ´Ù´Â °Í±îÁö Ãâ·ÂÇØ ÁÙ °ÍÀÔ´Ï´Ù:

case '?':
  /* getopt(3) prints "unknown option" message automatically. */
  fprintf(stderr, "Try `opt -h' for more information.\n");
  break;

´ÙÀ½À¸·Î, ÀÎÀÚ¸¦ ¹Þ´Â ¿É¼ÇÀÎ '-o FILE'¿¡ ´ëÇØ ´õ ¾Ë¾Æº¾½Ã´Ù. getopt(3)´Â ÀÎÀÚ¸¦ ¹Þ´Â ¿É¼ÇÀÌ µé¾î¿Ã °æ¿ì, Àü¿ª º¯¼ö optarg¿¡, ±× ¿É¼Ç ÀÎÀÚ¸¦ °¡¸®Å°´Â Æ÷ÀÎÅÍ °ªÀ» ÀúÀåÇØ µÓ´Ï´Ù. µû¶ó¼­ ¿ì¸®´Â ÀÌ optarg¿¡¼­ ¿øÇÏ´Â ÀÎÀÚ¸¦ ¾òÀ» ¼ö ÀÖ½À´Ï´Ù.

ÇÑ°¡Áö ´õ, optarg´Â getopt(3)¸¦ ºÎ¸¦ ¶§ ´Ù¸¥ °ªÀ¸·Î µ¤¾î ½á Áú ¼ö ÀÖÀ¸¹Ç·Î, ´ÙÀ½°ú °°Àº ÄÚµå´Â À§ÇèÇÒ ¼ö ÀÖ½À´Ï´Ù:

const char *filename;
...
filename = optarg;

°¡Àå ¼Õ½¬¿î ¹æ¹ýÀº strdup(3) ÇÔ¼ö¸¦ ½á¼­ ¸Þ¸ð¸®¸¦ ÇÒ´çÇÑ ´ÙÀ½, optarg°¡ °¡¸®Å°´Â ¹®ÀÚ¿­À» º¹»çÇÏ´Â °ÍÀÔ´Ï´Ù:

const char *filename;
...
filename = strdup(optarg);

¸¶Áö¸·À¸·Î, getopt(3)¸¦ ½á¼­ ¿É¼Ç 󸮸¦ ´Ù ³¡³Â´Ù¸é, ÀÌÁ¦ ÇÁ·Î±×·¥¿¡ Àü´ÞµÈ (¿É¼ÇÀÌ ¾Æ´Ñ) ÀÎÀÚµéÀ» ó¸®ÇØ¾ß ÇÕ´Ï´Ù. ÀÌ ¶§, ¿ì¸®´Â Àü¿ª º¯¼ö optind¿¡ ´ã±ä °ªÀ» ¾¹´Ï´Ù. optind¿¡´Â getopt°¡ argv[]¿¡ ÀÖ´Â ¿É¼ÇµéÀ» ó¸®ÇÏ°í ³­ ¸¶Áö¸· ÀÎÀÚ¿¡ ´ëÇÑ index °ªÀÌ µé¾î ÀÖ½À´Ï´Ù. µû¶ó¼­ ¿ì¸®´Â argv[optind]ºÎÅÍ argv[argc - 1]±îÁö ó¸®ÇÏ¸é µË´Ï´Ù. ¸¸¾à ÇÁ·Î±×·¥¿¡ Àü´ÞµÈ ÀÎÀÚµéÀÌ ¾ø´Â °æ¿ì¸¦ µû·Î ó¸®ÇÏ°í ½Í´Ù¸é, optind°¡ argc°¡ °°Àº °æ¿ì¸¦ ó¸®ÇÏ¸é µË´Ï´Ù. ¿¹¸¦ µé¾î À§ getopt¸¦ ¾´ while ¹®Àå ´ÙÀ½¿¡ ¾Æ·¡¿Í °°Àº Äڵ带 Ãß°¡ÇÏ¸é µË´Ï´Ù.

if (optind == argc) { /* there is no argument in the command-line. */
  ...
}
else {
  int i;
  for (i = optind; i < argc; i++) {
    /* process each argv[i] here */
    ...
  }
}


1.3. Skelton Template #1


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

#include <errno.h>
#include <error.h>


const char *program_name = "opt";
const char *version_string = "0.1";

int verbose_mode = 1;
const char *output_filename;

static void help_and_exit(void);
static void version_and_exit(void);


int
main(int argc, char *argv[])
{
  int c;

  while (1) {
    c = getopt(argc, argv, "hvo:q");
    if (c < 0)
      break;

    switch (c) {
    case 'h':
      help_and_exit();
      break;
    case 'v':
      version_and_exit();
      break;
    case 'q':
      verbose_mode = 0;
      break;
    case 'o':
      output_filename = strdup(optarg);
      break;
    case '?':
      error(0, 0, "Try `%s -h' for more information.\n", program_name);
      break;
    default:
      abort();
    }
  }

  if (optind == argc) {         /* There is no more argument in the
                                   command-line */
    /* TODO: insert code for no argument */
  }
  else {
    int i;
    for (i = optind; i < argc; i++) {
      /* Process each argv[i] here */
      printf("processing %s\n", argv[i]);
    }
  }

  return 0;
}


static void
help_and_exit(void)
{
  static const char *msgs[] = {
    "usage: opt [OPTION...] [FILES...]",
    "",
    "  -h       display this help and exit",
    "  -v       output version information and exit",
    "  -q       quite mode",
    "  -o       FILE send output to file FILE. If FILE is `-', ",
    "           send output to stdout.",
    "",
    "Report bugs to <cinsky at gmail dot com>",
  };
  int i;
  for (i = 0; i < sizeof(msgs) / sizeof(const char *); i++)
    puts(msgs[i]);
  exit(EXIT_SUCCESS);
}


static void
version_and_exit(void)
{
  printf("opt version %s\n", version_string);
  exit(EXIT_SUCCESS);
}



±Û¾´ÀÌ´Â Ç×»ó ÀÌ »À´ë Äڵ带 ÃÖ½ÅÀ¸·Î ¸¸µé·Á°í ÇÏ°í ÀÖ½À´Ï´Ù. ÃֽŠÄÚµå´Â ±Û¾´ÀÌÀÇ [http]CVS¿¡¼­ ¹Ù·Î º¼ ¼ö ÀÖ½À´Ï´Ù.

³¡ -- [http]½Å¼º±¹



ID
Password
Join
How you look depends on where you go.


sponsored by andamiro
sponsored by cdnetworks
sponsored by HP

Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2008-08-04 00:34:00
Processing time 0.0069 sec