LINUX.ORG.RU
ФорумTalks

Что-то конкурсов у нас давно не было... где моя K&R !

 , , , ,


0

6

Итак, взял я на досуге почитать незабвенный сабжевый труд наткнулся на задачу 6.1 — доработать функцию getword,

чтобы она корректно обрабатывала символы подчеркивания, директивы препроцессора, комментарии и строковые константы.

Программа, которую следует усовершенствовать такова:


#include <stdio.h>
#include <ctype.h>
#include <string.h>

#define MAXWORD 100
#define NKEYS (sizeof keytab / sizeof keytab[0])

struct key 
{
  char *word;
  int count;
} keytab[] = 
  {
    "auto", 0,
    "break", 0,
    "case", 0,
    "char", 0,
    "continue", 0,
    /*...*/
    "unsigned", 0,
    "void", 0,
    "volatile", 0,
    "while", 0
  };

int getword(char *, int);
int binsearch(char *, struct key *, int);

/* count C keywords */
int main(void)
{
  int n;
  char word[MAXWORD];

  while(getword(word, MAXWORD) != EOF)
    if (isalpha(word[0]))
      if ((n = binsearch(word, keytab, NKEYS)) >= 0)
	keytab[n].count++;
  for (n = 0; n < NKEYS; n++)
    if (keytab[n].count > 0)
      printf("%4d %s\n",
	     keytab[n].count, keytab[n].word);
  return 0;
}

/* binsearch: find word in tab[0]... tab[n-1] */
int binsearch(char *word, struct key tab[], int n)
{
  int cond;
  int low, high, mid;

  low = 0;
  high = n - 1;
  while (low <= high)
    {
      mid = (low + high) / 2;
      if ((cond = strcmp(word, tab[mid].word)) < 0)
	high = mid - 1;
      else if (cond > 0)
	low = mid + 1;
      else return mid;
    }
  return -1;
}

/* getword: get next word or character from input */
int getword(char *word, int lim)
{
  int c, getch(void);
  void ungetch(int);
  char *w = word;

  while (isspace(c = getch()))
    ;
  if (c != EOF)
    *w++ = c;
  if (!isalpha(c))
    {
      *w = '\0';
      return c;
    }
  for ( ; --lim > 0; w++)
    if (!isalnum(*w = getch()))
      {
	ungetch(*w);
	break;
      }
  *w = '\0';
  return word[0];
}

#define BUFFSIZE 100

char buf[BUFFSIZE];  // buffer for ungetch
int bufp = 0;        // next free posotion in buf

int getch(void)      // get a (possibly pushed back) character
{
  return (bufp > 0) ? buf[--bufp] : getchar();
}

void ungetch(int c)  // push back on input
{
  if (bufp >= BUFFSIZE)
    printf("ungetch: too many characters\n");
  else buf[bufp++] = c;
}

Я конечно все понимаю, но у меня вопрос, неужели для решения данной задачи в Си, который известен кратким и гибким синтаксисом, для вышеуказанного фикса нужно городить вот такую вот портянку?

Пример решения взят мной с clc-wiki.net

sudo cast beastie, tailgunner и все сишники включая Царя ;-)

Хочу увидеть краткий, красивый, ёмкий пускай и не быстрый код, реализующий эту задачу :-)

Вперёд!

Перемещено tailgunner из development

★★★★★

Ответ на: комментарий от Twissel

автор Вирт.

книга или построение компиляторов

или

проект Оберон.

в введении/вступлении/предисловии где то там.

qulinxao ★★☆
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.