我为K&R的C书中的练习编写了一个简单的#define处理器版本(练习6.3)。它非常简单,对于简单的输入很好。
但如果它遇到一个包含线,它就会断开。它不会用替换文本替换任何名称。它只是打印出准确的输入。
这是我的代码:

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

#define MAXWORD 100
#define SUCCESS 0

struct nlist {
    struct nlist *next;
    char *name;
    char *defn;
};

struct nlist *lookup(char *);
struct nlist *install(char *, char *);
int getword(char *, int);
int gettoken(char *, int);
int nl = 0;
int main()
{
    char word[MAXWORD], key[MAXWORD], value[MAXWORD], token[MAXWORD];
    struct nlist *res, *rres;
    FILE *fp = fopen("out", "w");
    res = NULL;

    while (getword(word, MAXWORD) != EOF) {
        fprintf(fp, "%s_", word);

        if (strcmp(word, "#define") == 0) {
            getword(key, MAXWORD);
            getword(value, MAXWORD);
            install(key, value);
            printf("%s %s %s\n", word, key, value);
        } else if (strcmp(word, "#include") == 0) {
            printf("%s ", word);
            gettoken(word, MAXWORD);
            printf("%s\n", word);
        } else if ((res = lookup(word)) != NULL) {
            printf("%s ", res->defn);
        } else {
            printf("%s ", word);
            if (!strcmp(word, ";")) printf("\n");
            else if (!strcmp(word, "{")) printf("\n");
            else if (!strcmp(word, "}")) printf("\n");
        }

    }


    return SUCCESS;
}

#define HASHSIZE 101

struct nlist *hashtab[HASHSIZE];

unsigned hash(char *s)
{
    unsigned hashval;

    for (hashval = 0; *s != '\0'; s++)
        hashval = *s + 31 * hashval;

    return hashval % HASHSIZE;
}

struct nlist *lookup(char *s)
{
    struct nlist *np;

    for (np = hashtab[hash(s)]; np != NULL; np = np->next)
        if (strcmp(s, np->name) == 0)
            return np;
    return NULL;
}

struct nlist *install(char *name, char *defn)
{
    struct nlist *np;
    unsigned hashval;
    char *mstrdup(char *);
    if ((np = lookup(name)) == NULL) {
        np = (struct nlist *) malloc(sizeof (*np));
        if (np == NULL || (np->name = mstrdup(name)) == NULL)
            return NULL;
        hashval = hash(name);
        np->next = hashtab[hashval];
        hashtab[hashval] = np;
    } else
        free((void *) np->defn);

    if ((np->defn = mstrdup(defn)) == NULL)
        return NULL;

    return np;
}

char *mstrdup(char *s)
{
    char *p = malloc(strlen(s) + 1);

    if (p != NULL)
        strcpy(p, s);

    return p;
}

int getch(void);
void ungetch(int);

int getword(char *word, int lim)
{
    int c;
    char *w = word;
    while (isspace(c = getch()))
        ;

    if (c != EOF)
        *w++ = c;

    if (!isalnum(c) && c != '#') {
        *w = '\0';
        return c;
    }

    for ( ; --lim > 0; w++) {
        *w = getch();
        if (!isalnum(*w) && *w != '_') {
            if (*w != '\n')
                ungetch(*w);
            break;
        }
    }

    if (*w == '\n')
        nl = 1;

    *w = '\0';

    return word[0];
}

int gettoken(char *token, int lim)
{
    int c;
    char *t = token;
    while (isspace(c = getch()))
        ;
    if (c == '<') {
        *t++ = c;
        for ( ; --lim > 0 && *t != '>'; )
            *t++ = getch();
        *t = '\0';
        return token[0];
    } else if (c == '\"') {
        *t++ = c;
        for ( ; --lim > 0 && *t != '\"'; )
            *t++ = getch();
        *t = '\0';
        return token[0];
    } else {
        strcpy(t, "Invalid token.");
        return 0;
    }

}
#define BUFF 100

char buff[BUFF];
char *bufp = buff;

int getch(void)
{
    return (bufp > buff) ? *--bufp : getchar();
}

void ungetch(int c)
{
    if (bufp < buff + BUFF)
        *bufp++ = c;
    else
        bufp = buff;
}

我要输入这个文件:d.txt
#define MAX 100
#define MIN 0


int main() {
int i = MAX;
printf("%d %d", i, MIN);
return MIN;
}

结果是:
$ ./defp < d.txt
#define MAX 100
#define MIN 0
int main ( ) {
int i = 100 ;
printf ( " % d % d " , i , 0 ) ; // notice the space between % and d It means that those characters was processed.
return 0 ;
}

但当输入包含#include <stdio.h>时,输出是:
$ ./defp < d.txt
#define MAX 100
#define MIN 0
#include <stdio.h>

int main() {
int i = MAX;
printf("%d %d", i, MIN); // notice that there are no spaces just the exact input means that the line wasn't proccessed.
return MIN;
}

为什么会这样,我不知道,请给我一个解释?

最佳答案

如注释中所述,下一个任务是学习如何使用调试器。
提示:错误在:

    *t++ = getch();

关于c - 为什么这个#define处理器遇到#include时表现奇怪?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33595301/

10-11 19:34