· 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
If you make a mistake you right it immediately to the best of your ability.


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.0073 sec