2015-11-08 38 views
0

我寫了一個#define處理器的簡單版本,用於練習K & R的C書(習題6.3)。它非常簡單,適用於簡單的輸入。 但是,如果它遇到了一個#include行就會中斷。它不會用替換文字取代任何名稱。它只是打印確切的輸入。 這裏是我的代碼:爲什麼當#define處理器遇到#include時會出現奇怪的現象?

#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; 
} 

爲什麼它是這樣的,我沒有任何想法,請給我一個解釋?

+3

TL; DR。提供[mcve]。使用調試器。 – Olaf

+0

並且不要在C中投放'malloc'和朋友(或'void *')的結果! – Olaf

+1

敢用調試器來調試你的代碼嗎? – alk

回答

2

正如評論中所說,您的下一個任務是學習如何使用調試器。

提示:該錯誤是:

*t++ = getch(); 
相關問題