0

我遇到过这样一个getword的例子。我了解所有检查等,但我对 ungetc 有疑问。

c满足if ((!isalpha(c)) || c == EOF)且不满足while (isalnum(c)) 时 -> 它不是字母,也不是数字 -ungetc拒绝那个char

让我们假设它是'\n'

然后它到达return word但是它不能被返回,因为它没有保存在任何数组中。那会发生什么?

    while (isalnum(c)) {
        if (cur >= size) {
            size += buf;
            word = realloc(word, sizeof(char) * size);

        }
        word[cur] = c;
        cur++;
        c = fgetc(fp);
    }
    if ((!isalpha(c)) || c == EOF) {
        ungetc(c, fp);          
    }
    return word;

编辑 @Mark Byers - 谢谢,但是 c 被拒绝是有目的的,并且不会在无限循环中一次又一次地满足条件?

4

3 回答 3

1

ungetc将字符推送到流中,以便下一次读取将再次返回该字符。

ungetc(c, fp);  /* Push the character c onto the stream. */
/* ...etc... */
c = fgetc(fp);  /* Reads the same value again. */

如果您正在读取字符以了解当前令牌何时完成,但尚未准备好读取下一个令牌,这有时会很方便。

于 2012-08-28T20:09:49.130 回答
1

终端条件,就在你不懂的那一行之前,不好。应该是:

int c;

...

if (!isalpha(c) && c != EOF)
    ungetc(c, fp);

这意味着如果读取的最后一个字符是真实字符(不是 EOF)并且不是字母字符,则将其推回以供接下来使用输入流的任何内容进行重新处理fp。也就是说,假设您阅读了一个空白;空白将终止循环,空白将被推回,以便下一个getc(fp)将再次读取空白(就像文件流fscanf()fread()的任何其他读取操作一样fp)。如果你得到的是 EOF 而不是空白,那么在我的修改后的代码中不会尝试推回 EOF;在原始代码中,EOF 将被推回。

请注意,c必须是 aint而不是 a char

于 2012-08-28T20:11:33.350 回答
0

好的。现在我明白为什么这种情况与例如。'\n'困扰着我。我只是愚蠢,忘记了main()提到getword的部分。当然,在调用 getword 之前,有几个测试(另一个ungetc在那里)并且fputs字符不令人满意isalnum 从这个while循环中出现的循环getword总是以至少一个isalnum正数开始,然后结束时的检查仅针对后续字符。

于 2012-08-28T20:47:08.630 回答