【问题标题】:C: Parsing a file with fgetc() - EOF infinite loopC:使用 fgetc() 解析文件 - EOF 无限循环
【发布时间】:2018-03-01 15:12:09
【问题描述】:

大家好@Stackoverflow,

目前我正在尝试为 .obj 文件格式编写一个简单的解析器,但不知何故,我的解析器在读取了 file.txt 中的最后一条注释后陷入了无限循环。 但它也发生在两者之间。

解析器应该执行以下操作:

如果当前字符是'#',它应该打印“COMMENT”并跳过这一行,如果它是一个'v',它应该打印“VERTEX”并跳过这一行。

即使我使用调试器单步调试我的代码,我仍然找不到问题。

文件.txt:

# Comment1
# Comment2
# Comment3
v Vertex1
# Comment4

代码:

int main()
{
    FILE *file = fopen("file.txt", "r");
    if(file==NULL)
    {
        return -1;
    }

    int currentChar=0;

    while(currentChar!=EOF)
    {
        currentChar=fgetc(file);
        printf("CURR CHAR: %c\n", currentChar);
        switch(currentChar)
        {
            case '#':
                {
                    printf("COMMENT\n");
                    currentChar=fgetc(file); //Read Whitespace 1x
                    while(currentChar!='\n')
                        currentChar=fgetc(file);
                    break;
                }
            case 'v':
                {
                    printf("VERTEX\n");
                    currentChar=fgetc(file); //Read Whitespace 1x
                    while(currentChar!='\n')
                        currentChar=fgetc(file);
                    break;
                }
            }
    }

    return 0;
}

我还是看不出问题出在哪里。

真诚地, 有毒

【问题讨论】:

  • currentChar 在进入 while() 之前未初始化。只需添加 currentChar=fgetc(file);之前
  • 可能不是问题的原因,但在初始化之前测试currentChar 是错误的。
  • @ShihabPullissery 我也用 int currentChar=0;在进入while循环之前。仍然陷入无限循环。
  • @t0XiC 此代码 while(currentChar!='\n') currentChar=fgetc(file);可以调用无限循环。
  • 解决方案可能是有限状态机。 (需要 4 个州中的 3 个)

标签: c parsing infinite-loop eof fgetc


【解决方案1】:

看起来它在等待换行符时被卡住了。您的开关盒中的循环可能是罪魁祸首。将循环更改为:

    while(currentChar != EOF && currentChar != '\n')

【讨论】:

  • ... 和 currentChar 应该被初始化,例如:int currentChar= 0;
  • 我试过这个,但它不会读取我的带有 'v's 的行。从file.txt中读取第一个'#'后,它会自动退出循环
  • @t0XiC 当然不行,读取顶点行的代码不是你写的
  • @t0XiC 向我们展示了一个可重现的示例,当您使用 0 对其进行初始化时,它无法正常工作
  • @t0XiC 你需要用有限状态机来解决这个问题,其他的一切都会以泪水告终
【解决方案2】:

你可能想要这个:

#include <stdio.h>

int main()
{
  FILE *file = fopen("file.txt", "r");
  if (file == NULL)
  {
    return -1;
  }

  int currentChar = 0;

  while (currentChar != EOF)
  {
    currentChar = fgetc(file);

    if (currentChar == EOF)    // if EOF stop loop immediately,
                               // it's pointless to continue
      break;

    printf("CURR CHAR: %c\n", currentChar);
    switch (currentChar)
    {
      case '#':
      {
        printf("COMMENT\n");
        currentChar = fgetc(file); 
        while (currentChar != EOF && currentChar != '\n')   // skip until \n or EOF
          currentChar = fgetc(file);
        break;
      }
      case 'v':
      {
        printf("VERTEX: <");
        currentChar = fgetc(file);

        while (currentChar != EOF && currentChar != '\n')   // read until \n or EOF
        {
          printf("%c", currentChar);
          currentChar = fgetc(file);
        }

        printf(">\n");
        break;
      }
    }
  }

  return 0;
}

它很大程度上基于您的原始代码。所有的cmets都是我的。

【讨论】:

  • 这行得通,我会尽力理解它,非常感谢(Vielen Dank!)!
  • 这几乎是您的原始代码,大致上您只是忘记阅读v之后的字符
猜你喜欢
  • 2012-10-26
  • 2013-01-11
  • 1970-01-01
  • 1970-01-01
  • 2019-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-09
相关资源
最近更新 更多