GetChar() 函数奇怪
GetChar() function strange
- 列表项
我在使用 getchar()
时遇到问题 method.What 我正在尝试计算一个小型汇编模拟器,其中包含 8 个命令,这些命令由用户以 ADD Rx Ry
的形式编写,其中 Rx
和 Ry
是寄存器。我不允许使用字符串或数组,所以唯一的选择是逐个读取字符。
我的问题是我不知道如何从一行输入文本中读取多个字符并将其放入 variables.For 示例中,ADD Rx Ry
我想存储 A
在 ch1
中,D
在 ch2
中,在 D
中,在 ch3
中,然后跳过 space 验证 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);
你也必须阅读换行符。此外,您必须刷新 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
是这样的:
- 用户输入
ADD\n
(4 个字符)。
ADD
扫描,ch1
包含'A'
,ch2
包含'D'
,ch3
包含'D'
。 '\n'
留在 stdin
.
- 下一次迭代来了。用户再次输入
ADD\n
。
- 但是,
stdin
中还剩下 '\n'
,所以 ch1
包含 '\n'
,ch2
包含 'A'
, ch3
包含 'D'
并且 stdin
中还有 D\n
剩余。
当您开始向终端输入数据时,假设您首先输入了 "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;
}
当用户键入 "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);
- 列表项
我在使用 getchar()
时遇到问题 method.What 我正在尝试计算一个小型汇编模拟器,其中包含 8 个命令,这些命令由用户以 ADD Rx Ry
的形式编写,其中 Rx
和 Ry
是寄存器。我不允许使用字符串或数组,所以唯一的选择是逐个读取字符。
我的问题是我不知道如何从一行输入文本中读取多个字符并将其放入 variables.For 示例中,ADD Rx Ry
我想存储 A
在 ch1
中,D
在 ch2
中,在 D
中,在 ch3
中,然后跳过 space 验证 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);
你也必须阅读换行符。此外,您必须刷新 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
是这样的:
- 用户输入
ADD\n
(4 个字符)。 ADD
扫描,ch1
包含'A'
,ch2
包含'D'
,ch3
包含'D'
。'\n'
留在stdin
.- 下一次迭代来了。用户再次输入
ADD\n
。 - 但是,
stdin
中还剩下'\n'
,所以ch1
包含'\n'
,ch2
包含'A'
,ch3
包含'D'
并且stdin
中还有D\n
剩余。
当您开始向终端输入数据时,假设您首先输入了 "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;
}
当用户键入 "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);