E x c e r c i s e 6 − 1 Excercise\quad 6-1 Excercise6−1:
#include <stdio.h>
#include <ctype.h>
#include <string.h>
/*
Exercise 6-1. Our version of getword does not properly handle underscores, string constants, comments, or preprocessor control lines. Write a better version.
*/
struct key {
char *word;
int count;
} keytab[] =
/* Current keywords as of C17 standard (ISO/IEC 9899:2017). These must be in alphabetical order */
{
{
"_Alignas", 0 }, {
"_Alignof", 0 }, {
"_Atomic", 0 }, {
"_Bool", 0 }, {
"_Complex", 0 }, {
"_Generic", 0 },
{
"_Imaginary", 0 }, {
"_Noreturn", 0 }, {
"_Static_assert", 0 }, {
"_Thread_local", 0 }, {
"auto", 0 }, {
"break", 0 },
{
"case", 0 }, {
"char", 0 }, {
"const", 0 }, {
"continue", 0 }, {
"default", 0 }, {
"do", 0 },
{
"double", 0 }, {
"else", 0 }, {
"enum", 0 }, {
"extern", 0 }, {
"float", 0 }, {
"for", 0 },
{
"goto", 0 }, {
"if", 0 }, {
"inline", 0 }, {
"int", 0 }, {
"long", 0 }, {
"register", 0 },
{
"restrict", 0 }, {
"return", 0 }, {
"short", 0 }, {
"signed", 0 }, {
"sizeof", 0 }, {
"static", 0 },
{
"struct", 0 }, {
"switch", 0 }, {
"typedef", 0 }, {
"union", 0 }, {
"unsigned", 0 }, {
"void", 0 },
{
"volatile", 0 }, {
"while", 0 }
};
#define MAXWORD 100
#define NKEYS (int)(sizeof keytab / sizeof keytab[0])
#define BUFSIZE 100
int getword(char *, int);
int binsearch(char *, struct key *, int);
int getch(void);
void ungetch(int);
enum statusTypes {
NORMAL, STRING, SINGLE_LINE_COMMENT, MULTI_LINE_COMMENT, PREPROCESSOR };
char prevChar='\0'; /* keep track of last char */
int type=NORMAL; /* keep track of the current status */
char buf[BUFSIZE]; /* buffer for ungetch */
int bufp = 0; /* next free position in buf */
/* count C keywords */
int main()
{
int n;
char word[MAXWORD];
while (getword(word, MAXWORD) != EOF)
{
if (word[0] == '"')
{
if (type == NORMAL && prevChar != '\'')
{
type = STRING;
}
else if (type == STRING)
type = NORMAL;
}
else if (word[0] == '/')
{
if (prevChar == '/' && type == NORMAL)
type = SINGLE_LINE_COMMENT;
else if (type == MULTI_LINE_COMMENT && prevChar == '*')
type = NORMAL;
}
else if (word[0] == '\n' && (type == SINGLE_LINE_COMMENT || type == PREPROCESSOR))
type = NORMAL;
else if (word[0] == '*' && prevChar == '/' && type == NORMAL)
type = MULTI_LINE_COMMENT;
else if (word[0] == '#' && prevChar == '\n')
type = PREPROCESSOR;
if (type == NORMAL && (isalpha(word[0]) || word[0] == '_'))
if ((n = binsearch(word, keytab, NKEYS)) >= 0)
keytab[n].count++;
if (strlen(word) == 1)
prevChar = word[0];
}
for (n = 0; n < NKEYS; n++)
if (keytab[n].count > 0)
printf("%4d %s\n", keytab[n].count, keytab[n].word);
return 0;
}
/* find word in tab[0] ... tab[n-1], tab[] must be in alphabetical order */
int binsearch(char *word, struct key tab[], int n)
{
int result, mid, low = 0, high = n - 1;
while (low <= high)
{
mid = (low + high) / 2;
if ((result = strcmp(word, tab[mid].word)) < 0)
high = mid - 1;
else if (result > 0)
low = mid + 1;
else
return mid;
}
return -1;
}
/* get next word or character from input */
int getword(char *word, int lim)
{
int c;
char *w = word;
while ((c = getch()) == '\t' || c == ' ')
;
if (c != EOF)
*w++ = c;
if (!isalpha(c) && c != '_')
{
*w = '\0';
return c;
}
for ( ; --lim > 0; w++)
if (!isalnum(*w = getch()) && *w != '_')
{
ungetch(*w);
break;
}
*w = '\0';
return word[0];
}
/* get a (possibly pushed back) character */
int getch(void)
{
return (bufp > 0) ? buf[--bufp] : getchar();
}
/* push character back on input */
void ungetch(int c)
{
if (bufp >= BUFSIZE)
printf("ungetch: too many characters\n");
else
buf[bufp++] = c;
}
E x c e r c i s e 6 − 2 Excercise\quad 6-2 Excercise6−2:这里需要注意的是对于一个变量 X X X,只有在至少有一个变量且这个变量从第一个字符开始至少有一个连续的字符和变量 X X X从第一个字符开始的一个连续的字符相同的情况下。变量 X X X才会被打印出来,否则这个变量不会被打印出来。假设现在输入了以下变量:
- abc
- aac
- azc
- dsx
- bdc
- bac
- bgc
将会输出(dsx不会输出):
- aac
- abc
- azc
- bac
- bdc
- bgc
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
struct tnode
{
char *word;
struct tnode *left;
struct tnode *right;
};
#define MAXWORD 100
#define BUFSIZE 100
#define DEFAULT_NUM_CHARS 6 /* default number of chars to compare in a string */
#define KEYWORD_LEN 44 /* C17 standard has 44 keywords */
struct tnode *addtree(struct tnode *, char *);
struct tnode *talloc(void);
void treeprint(struct tnode *, struct tnode *root);
int getword(char *, int);
int binsearch(char *);
int getword(char *word, int lim);
int getch(void);
void ungetch(int);
/* strdup conflicts with function name from strings.h so it was renamed to mystrdup */
char *mystrdup(char *);
enum statusTypes {
NORMAL, STRING, SINGLE_LINE_COMMENT, MULTI_LINE_COMMENT, PREPROCESSOR };
enum boolean {
FALSE, TRUE };
char *keywords[KEYWORD_LEN] =
/* Current 44 keywords as of C17 standard (ISO/IEC 9899:2017). These must be in alphabetical order */
{
"_Alignas", "_Alignof", "_Atomic", "_Bool", "_Complex", "_Generic", "_Imaginary", "_Noreturn", "_Static_assert", "_Thread_local",