2012-08-28 18 views
0

我遇到过这样一个getword的例子。 我明白所有的检查等,但我有ungetc的问题。了解ungetc在一个简单的getword中使用

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; 

编辑 @马克拜尔斯 - 感谢,但c的拒绝是有目的的,而不会在一个无限循环一次又一次满足条件?

+1

这是一个'getword'功能,而不是'getwordahdonemorecharacterww anyitmaybe''。它会读取,直到遇到不是字母数字的字符。然后它将该角色放回流中并返回。大概它会返回一个字符指针,但是你省略了函数声明,所以我不能100%确定。循环后的if语句中的'!isalpha(c)'等同于真,因为字符永远不会是字母的(如果是的话,循环就不会被破坏)。除非循环在错误处理过程中能够中断。 – Wug

回答

1

终端条件,就在您不理解的行之前,并不好。它可能应该是:

int c; 

... 

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

这意味着,如果最后一个字符阅读是一个真正的字符(不是EOF),是不为英文字母,由何体统采用输入流fp它推回去重新处理。也就是说,假设你读了一个空白;空白将终止循环,空白将被推回,以便下一个getc(fp)将再次读取空白(如fscanf()fread()或对文件流fp的任何其他读取操作)。如果不是空白的,你得到了EOF,那么在我的修改后的代码中没有试图推回EOF;在原始代码中,EOF将被推回。

请注意,c必须是int而不是char

+0

我把它定义为'int'。请参阅我的编辑,因为在我看来,例如。 '\ n'会以无限循环结束。 –

+0

@PeterKowalski:为什么?在第一次迭代中,如果它读取换行符作为第一个字符,则循环终止,换行符被推回,单词为空,代码(未显示)处理代码的非单词部分(可能是代码跳过空白?)将处理它。如果它是第二个或后续字符,则循环终止并且该单词不为空,则换行将换行以处理代码的非单词部分。请注意,我(不得不)假设代码来读取非单词字符。 - 我从你的回答中看出你也是这样做的。 –

1

ungetc将字符压入流中,以便下一次读取将再次返回该字符。

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

有时这可能是方便,如果你正在阅读的文字,找出当前标记完成后,但尚未准备好读下一个标记。

+0

谢谢,但你能看到我的编辑? –

+0

@PeterKowalski:你展示的代码没有无限循环。如果存在无限循环,那么它可能是调用此函数的代码中的一个错误。 –

+0

程序工作正常,我只是想象任何输入,并在读取它时调用过程。 –

0

好的。现在我明白为什么例如。 '\n'让我感到困扰。我只是笨手笨脚的,忘记了main()中涉及到getword的部分。当然,在调用之前朗朗上口有一对夫妇的测试(另一个ungetc那里),它fputs不是satisying字符isalnum 从这个是while环路getword总是与至少一个isalnum阳性,检查在然后结束是开始浮现只适用于以下字符。