Упражнение K & R 6-1 В некоторых случаях функция getword не может прочитать EOF - PullRequest
1 голос
/ 08 ноября 2019

Я только что закончил упражнение 6.1 в книге Язык программирования C , Второе издание (K & R ), вот проблема упражнения:

Наша версия getword неправильно обрабатывает подчеркивания, строковые константы, комментарии или строки управления препроцессором. Напишите лучшую версию.

Вот функция getword из книги:


    int getword(char *word, int lim)
    {
        int c;
        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];
    }

Вызов функции в main ():


    while (getword(word, MAXWORD) != EOF) {...}

Здесьмоя функция getword:

int getword(char *word, int lim)
{
    int c, c1;
    char *w = word;
    while (isspace(c = getch()))
        ;
    if (c != EOF)
        *w++ = c;
    else    
        return EOF;
   // handle comments: /* */ 
    if ( c == '/') {
        if ((c1 = getch()) == '*') {
            keytab[31].count++;
            int ok = 1;
            while (ok) {
                // skip characters in comment lines
                while ((c = getch()) != EOF || c != '*')
                    ;
                if (c == EOF)
                    return EOF;
                if ((c = getch()) == '/')
                    ok = 0;
            }
            return COMMENT;
        }
         // handle comments : //
        else if (c1 == '/') {
            keytab[32].count++;
            while ((c = getch()) != EOF || c != '\n')
                ;
            if (c == EOF)
                return EOF;
            return COMMENT;
        }
        else
            return c;
    }
    // handle preprocessor control lines, start with '#'
    if (c == '#') {
        keytab[34].count++;
        while ((c = getch()) != EOF || c != '\n')
            ;
        if (c == EOF)
            return EOF;
        return '#';
    }
    // handle string constants, " "
    else if (c == '\"') {
        while ((c1 = getch()) != EOF || c1 != '\"')
            ;
        if (c1 == EOF)
            return EOF;
        keytab[33].count++;
        return CONSTANT;
    }
    else if (c != '_' && !isalpha(c)) {
        while ((c = getch()) != EOF && !isspace(c))
            ;
        if (c == EOF)
            return EOF;
        return NOT;
    }
    // c is '_' or letter , scan characters until EOF or space, or punctuation
    // to get a complete word
    for ( ; --lim > 0; w++)
        if ((*w = getch()) == EOF || isspace(*w) || ispunct(*w)) {
            ungetch(*w);
            break;
        }
    *w = '\0';
    return WORD;
}

Если я не введу ", // , / * или #, код будет работать нормально, и я могу остановить ввод с помощью enterint ctrl + d. Но как только я введу один из вышеперечисленных символов, программа не сможет прочитать EOF, поэтому я не могу остановить ввод. Я отлаживаюпрограмма от GDB, но до сих пор не понимаю. Так что же происходит?

1 Ответ

1 голос
/ 08 ноября 2019

&& против ||

while ((c = getch()) != EOF || c != '*')

Выше всегда верно.

Возможно

while ((c = getch()) != EOF && c != '*')
...