K&R 练习 6-1 某些情况下 getword 函数无法读取 EOF
K&R Exercise 6-1 In some cases getword function can't read EOF
我刚刚完成书The C Programming Language,第二版中的练习6.1 (by K&R),这里是练习题:
Our version of getword does not properly handle underscores, string constants,
comments, or preprocessor control lines. Write a better version.
这里是书上的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 = '[=10=]';
return c;
}
for ( ; --lim > 0; w++)
if (!isalnum(*w = getch())) {
ungetch(*w);
break;
}
*w = '[=10=]';
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 = '[=12=]';
return WORD;
}
如果我不输入 ", // , /* 或 #,代码会正常运行,我可以通过enterint ctrl + d停止输入。但是一旦我输入了上述字符之一,程序就无法读取EOF,因此无法停止输入,用gdb调试程序还是不明白,怎么回事?
&&
对比 ||
while ((c = getch()) != EOF || c != '*')
以上总是正确的。
也许
while ((c = getch()) != EOF && c != '*')
我刚刚完成书The C Programming Language,第二版中的练习6.1 (by K&R),这里是练习题:
Our version of getword does not properly handle underscores, string constants, comments, or preprocessor control lines. Write a better version.
这里是书上的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 = '[=10=]';
return c;
}
for ( ; --lim > 0; w++)
if (!isalnum(*w = getch())) {
ungetch(*w);
break;
}
*w = '[=10=]';
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 = '[=12=]';
return WORD;
}
如果我不输入 ", // , /* 或 #,代码会正常运行,我可以通过enterint ctrl + d停止输入。但是一旦我输入了上述字符之一,程序就无法读取EOF,因此无法停止输入,用gdb调试程序还是不明白,怎么回事?
&&
对比 ||
while ((c = getch()) != EOF || c != '*')
以上总是正确的。
也许
while ((c = getch()) != EOF && c != '*')