GetChar()函数很奇怪

时间:2017-09-26 07:50:27

标签: c io getchar

  • 列表项

我使用getchar()方法时遇到问题。我正在尝试计算一个小型程序集模拟器,其中包含8个命令,这些命令由用户在ADD Rx Ry Rx形式下编写, Ry是寄存器。我不允许使用字符串或数组,因此唯一的选择是通过char读取char。

我的问题是我不知道如何从一行输入文本中读取多个字符并将其放在变量中。例如,ADD Rx Ry我想将A存储在{{1}中{}}中的ch1D中的ch2D中的ch3然后跳过空格验证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);

3 个答案:

答案 0 :(得分:0)

你也必须阅读换行符。此外,您必须刷新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. 扫描了
  3. ADDch1包含'A'ch2包含'D'ch3包含'D''\n'保留stdin
  4. 下一次迭代来了。用户再次输入ADD\n
  5. 但是,上一次扫描的'\n'内有stdin,因此ch1包含'\n'ch2包含'A',{ {1}}包含ch3'D'中有D\n个剩余。

答案 1 :(得分:0)

当您开始在终端中输入数据时,首先输入" 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;

}

答案 2 :(得分:0)

当用户键入“ADD Rx Ry”时,他将按Enter键。

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);