【问题标题】:GetChar() function strangeGetChar() 函数奇怪
【发布时间】:2017-09-26 07:50:27
【问题描述】:
  • 列表项

我在使用getchar() 方法时遇到问题。我正在尝试计算一个小型装配模拟器,其中包含用户以ADD Rx Ry 形式编写的8 个命令,其中RxRy 是寄存器.我不允许使用字符串或数组,所以唯一的选择是逐字符读取。

我的问题是我不知道如何从输入文本的一行中读取多个字符并将其放入变量中。例如ADD Rx Ry我想将A存储在ch1中,Dch2Dch3 然后跳过空格验证R 并将x 存储在一个变量中,然后对于y 也是如此。

奇怪的是,当我在第一个命令之后输入第二个命令时,下面显示的程序不会显示完全相同的打印值(打印只是为了调试)

do{
  ch1=getchar();
  ch2=getchar();
  ch3=getchar();
  if(ch1=='E' && ch2=='N'&& ch3=='D'){
    break;
  }
    printf("%c",ch1);
    printf("%c",ch2);
    printf("%c",ch3);
}while(1);

【问题讨论】:

  • 你有什么意见?它包括换行符吗?你读过换行符吗?你期望什么输出?你得到什么输出?
  • 你也必须阅读换行符。

标签: c io getchar


【解决方案1】:

当用户输入“ADD Rx Ry”时,他会回车。

getchar() 一次消耗一个字符。

因此,为了使用此输入,您需要调用 getchar() 8 次,3 次用于“ADD”,2 次用于空白,4 次用于寄存器。

现在你想输入“ADD Ri Rj”,所以你认为你需要再次调用getchar() 8次。

getchar() 的第一次调用将消耗前一个输入的尾随换行符(当用户按 Enter 时)!它不会像您希望的那样消耗“A”。

因此,当键入“END”时,getchar() 将使用来自先前输入(如果有)的尾随换行符和字符。

因此,只需使用尾随换行符(并继续循环,因为您不想处理换行符,只是为了使用它),如下所示:

do {
  ch1 = getchar();
  if(ch1 == '\n')
    continue;
  ch2 = getchar();
  if(ch2 == '\n')
    continue;
  ch3 = getchar();
  if(ch3 == '\n')
    continue;
  ch4 = getchar();
  if(ch4 == '\n')
    continue;

  if(ch1=='E' && ch2=='N'&& ch3=='D') {
    break;
  }
} while(1);

【讨论】:

    【解决方案2】:

    当你开始在终端输入数据时,首先说你输入了“ADD\n”,

    • A 存储在 ch1 中
    • D 存储在 ch2 中
    • D 存储在 ch3 中

    '\n' 被发送到缓冲区。现在第二次开始输入新的字符集,比如“SUB”,getchar() 开始从缓冲区读取,它遇到的第一个字符是 '\n',依此类推, 因此

    • ch1 = '\n'
    • ch2 = 'S'
    • ch3 = 'U'

    解决问题的更好方法是在所有三个 getchar() 之后添加一个 getchar(),这将消耗额外的 '\n' 并且不会打印相同的内容。

    do{
       ch1=getchar();
       ch2=getchar();
       ch3=getchar();
       getchar();
    
     if(ch1=='E' && ch2=='N'&& ch3=='D'){
        break;
      }
        printf("%c",ch1);
        printf("%c",ch2);
        printf("%c",ch3);
    }while(1);
    return 0;
    

    }

    【讨论】:

      【解决方案3】:

      您也必须阅读换行符。此外,您必须在扫描后刷新stdin 以删除任何多余的输出。如果你不能使用字符串和数组,而唯一的选择是使用getchar,你将没有手动管理4个字符的缓冲区,这不会很漂亮。

      char ch1, ch2, ch3, ch4;
      do {
          ch1 = getchar(); if (ch1 == '\n') continue;
          ch2 = getchar(); if (ch2 == '\n') continue;
          ch3 = getchar(); if (ch3 == '\n') continue;
          ch4 = getchar(); if (ch4 != '\n') continue;
          if (ch1 == 'E' && ch2 == 'N' && ch3 == 'D' && ch4 == '\n') break;
      } while (1);
      

      如果不考虑换行符并刷新stdin,会发生什么情况:

      1. 用户输入ADD\n(4 个字符)。
      2. ADD 被扫描,ch1 包含 'A'ch2 包含 'D'ch3 包含 'D''\n' 留在 stdin 中。
      3. 下一次迭代来了。用户再次输入ADD\n
      4. 但是,上次扫描的stdin 中还剩下'\n',所以ch1 包含'\n'ch2 包含'A'ch3 包含'D' 并且有@98765444剩余在stdin

      【讨论】:

      • @Bob__ 还有?我的代码与 OP 的代码不同,因为 OP 的代码已损坏。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-12
      • 1970-01-01
      • 2014-05-31
      相关资源
      最近更新 更多