提问人:Pavel Straka 提问时间:11/9/2017 最后编辑:Petr SkocikPavel Straka 更新时间:11/11/2017 访问量:999
直到 CTRL + D 的输入间隔
Intervals on input until CTRL + D
问:
我有写成我阅读的间隔,但问题是我需要在许多这样的间隔内使用我的函数,直到我在 Unix 上按下 或。<a;b>
scanf("<%d;%d>", &a, &b);
CTRL + Z
CTRL + D
到目前为止,我尝试过这样的东西,但它不起作用。
int main( void ) {
int a=0, b=0;
printf("Intervals:\n");
while(scanf("<%d;%d>", &a, &b) == 2 && !feof(stdin)){
printf("Distinct rectangular cuboids: %d\n", capacities(a, b));
}
return 0;
答:
你的问题不简明扼要。这:
int main( void ) {
int a=0, b=0;
printf("Intervaly: \n");
while(scanf("<%d;%d>",&a,&b) == 2){
printf("Ruznych kvadru: %d\n", capacity(a, b));
}
return 0;
}
实际上做你想要的,无论是长线还是一行一行 - 两者都可以工作。您的问题隐藏在评论中,EOF 不会立即终止它 - 而是您需要按 CTRL-D 两次才能停止它。原因也在评论中。<%d;%d>
一旦你以你的方式扫描,你将在输入流中留下一个(因为你必须按回车键才能在不终止的情况下发送你的输入)。有两种方法可以解决这个问题 - 将其添加到 中,它不太灵活并且存在一些问题,或者在 while 中清除它:\n
scanf
while(scanf("<%d;%d>",&a,&b) == 2){
printf("Ruznych kvadru: %d\n", capacity(a, b));
getchar();
}
您会发现现在您需要按一次 CTRL-D。如果您尝试从文件进行输入重定向,您会看到此问题也不存在。为什么会这样?您在输入流中。您按 EOF,因此 scanf 会获得一个换行符并忽略它 - 等待新输入。只有现在,新的 EOF 才会杀死 .\n
scanf
我建议在这个网站上搜索问题,看看为什么不使用它,以及其他不错的选择。scanf
补遗
评论中给出的更优雅的解决方案,@BluePixy向我指出,@DavidBowling向我指出,用于您的:scanf
scanf("<%d;%d>%*c", &a, &b);
这自然会吞噬额外的字符,包括新空间,而不需要额外的.我认为这是这种用法最优雅的解决方案。getchar
scanf
愈
在 OP 和 David 的评论之后(再次感谢!)为了考虑 0 个或更多空格,您只需要格式中的空格指令:
scanf("< %d ; %d >%*c", &a, &b);
现在,可以在每个整数周围添加空格(也可能不会)。
评论
scanf
scanf()
scanf("<%d;%d>\n",&a,&b)
scanf(“<%d;%d>%*c”, &a, &b)
呢?在这里,在一行上可以有多个输入(只要它们之间只有一个字符;您的解决方案需要相同的字符)。scanf()
scanf()
scanf
至于循环条件,应该就足够了,但你可能还应该跟踪数字以进行错误诊断:while( scanf(" <%d;%d>", &a, &b)) == 2 )
int nread=2;
while( (nread=scanf(" <%d;%d>", &a, &b)) == 2){ //...
这部分更复杂。 导致规范设置的终端驱动程序生成信号。Ctrl-Z
Ctrl-Z
SIGTSTP
此信号的默认处理是将进程置于睡眠状态,这意味着您
不能简单地使用 ISO C 的函数来注册信号处理程序,因为
如果出现以下情况,这些信号处理程序可能会无意中恢复原始信号处置
接收到多个信号实例,这将使您的进程停止。signal
您需要进入 POSIX 并使用 .sigaction
然后,处理程序可以设置一个易失性标志,这将是终止循环的信号。
由于在内部接收信号会导致失败,因此对此的鲁棒错误处理有点复杂:sigaction
scanf
scanf
EINTR
#include <stdio.h>
#include <signal.h>
#include <errno.h>
static int volatile ctrl_z;
void SignalHandler( int Signum )
{
(void)Signum;
ctrl_z=1;
}
int main( void ) {
// ctrl + z
sigaction(SIGTSTP, &(struct sigaction){ .sa_handler=SignalHandler }, 0);
int a=0, b=0, nread=2;
/*...*/
while( (nread=scanf(" <%d;%d>", &a, &b)) == 2){
/*...*/
if(ctrl_z)
return 0;
errno=0; /*so we know if scanf failed because of the signal*/
}
if ( (!ferror(stdin) && feof(stdin)) ||
(ferror(stdin) && errno==EINTR && ctrl_z) )
return 0;
return 1;
}
评论
while(scanf(" <%d;%d>", &a, &b) == 2){
CTRL + D
while(scanf("<%d;%d>%*c", &a, &b) == 2){
scanf("<%d;%d>", &a, &b) == 2
!feof(stdin)
scanf("<%d;%d>", &a, &b)
将尾随留在 中。读一行,然后'\n'
stdin
fgets()
sscanf(buffer, "<%d;%d>", &a, &b)