Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 而循环在输入有效输入后挂起程序?_C_While Loop_Freeze - Fatal编程技术网

C 而循环在输入有效输入后挂起程序?

C 而循环在输入有效输入后挂起程序?,c,while-loop,freeze,C,While Loop,Freeze,从昨晚开始,我就时断时续地被这个问题困扰着,我希望第二双新的眼睛会有所帮助 问题是,如果在userIn函数中输入了无效输入(任何不是1-99之间的数字),则main中while循环末尾的测试printf打印“ERR=1”,while循环和userIn将再次调用。到目前为止还不错,但当输入有效输入时,while循环末尾的testprintf打印“ERR=0”,然后程序挂起。说“你好”的测试打印永远不会打印出来 任何关于原因的建议都是最受欢迎的 守则: #include <stdio.h>

从昨晚开始,我就时断时续地被这个问题困扰着,我希望第二双新的眼睛会有所帮助

问题是,如果在
userIn
函数中输入了无效输入(任何不是1-99之间的数字),则
main
中while循环末尾的测试printf打印“ERR=1”,while循环和
userIn
将再次调用。到目前为止还不错,但当输入有效输入时,while循环末尾的testprintf打印“ERR=0”,然后程序挂起。说“你好”的测试打印永远不会打印出来

任何关于原因的建议都是最受欢迎的

守则:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

void userIn (int *x)
    {
    char b;
    printf("Please enter a new value for Vm: ");
    scanf(" %i",x);
    while (((b=getchar())!='\n')&&(b!=EOF));
    return; 
    }
int main (void)
    {
    int  fd, x, err;
    char *npipe = "/tmp/fms",
         input[3];
    struct stat info;
    printf("\n");

    //get user input
    err = 1;
    while (err)
        {
        userIn(&x);
        if (x > 0 && x < 100) err = 0;
        //else printf("\033[1A\033[K");

        printf("ERR = %i\n",err);//TEST PRINTF
        }
    printf("HELLO");//TEST PRINTF

    //if pipe exists
    if ( (!lstat(npipe,&info)) && (S_ISFIFO(info.st_mode)) )
        {
        sprintf(input,"%i",x);
        //write user input to named pipe created by 'parent.c'
        fd = open(npipe, O_WRONLY);
        write(fd, input, sizeof(input));
        close(fd);
        }
    else printf("\033[0;31mNamed pipe doesn't exist, %i not passed.\n\n\033[0m",x);
    return 0;
    }
#包括
#包括
#包括
#包括
#包括
#包括
void userIn(int*x)
{
字符b;
printf(“请为Vm:”输入一个新值);
scanf(“%i”,x);
而(((b=getchar())!='\n')&&(b!=EOF));
返回;
}
内部主(空)
{
int-fd,x,err;
char*npipe=“/tmp/fms”,
输入[3];
结构统计信息;
printf(“\n”);
//获取用户输入
误差=1;
虽然(错误)
{
userIn&x;
如果(x>0&&x<100)err=0;
//else printf(“\033[1A\033[K”);
printf(“ERR=%i\n”,ERR);//测试printf
}
printf(“HELLO”);//测试printf
//如果管道存在
如果(!lstat(npipe,&info))&(S_ISFIFO(info.st_模式)))
{
sprintf(输入,“%i”,x);
//将用户输入写入由“parent.c”创建的命名管道
fd=打开(仅适用于管道,O_);
写入(fd,输入,sizeof(输入));
关闭(fd);
}
else printf(“\033[0;31M命名管道不存在,%i未通过。\n\n\033[0m”,x);
返回0;
}

与您的直觉相反,程序冻结在
printf(“HELLO”);
行之后的某个位置。由于该printf中没有换行符,
HELLO
会被缓冲,不会立即刷新到终端


是否有一个进程从你的管道的另一端读取数据?

与你的直觉相反,程序在
printf(“HELLO”);
行之后的某个地方冻结。由于该printf中没有换行符,
HELLO
会被缓冲,不会立即刷新到终端


是否有进程从您的管道的另一端读取数据?

如果我在我的系统上运行您的代码,则输出如下所示:

Please enter a new value for Vm: 101
ERR = 1
Please enter a new value for Vm: 1
ERR = 0
HELLONamed pipe doesn't exist, 1 not passed.
也就是说,循环会在您认为应该的时候退出。当然,代码会立即退出,因为我的系统上不存在
/tmp/fms

但是,如果我创建
/tmp/fms
,那么我会看到:

Please enter a new value for Vm: 1
ERR = 0

…并且没有额外的输出。这是因为
printf
语句的输出被缓冲,并且对指定管道的写入被阻塞,因此输出永远不会被刷新。向printf添加
\n
可能会像您期望的那样显示它。

如果我在我的系统上运行您的代码,则输出如下所示:

Please enter a new value for Vm: 101
ERR = 1
Please enter a new value for Vm: 1
ERR = 0
HELLONamed pipe doesn't exist, 1 not passed.
也就是说,循环会在您认为应该的时候退出。当然,代码会立即退出,因为我的系统上不存在
/tmp/fms

但是,如果我创建
/tmp/fms
,那么我会看到:

Please enter a new value for Vm: 1
ERR = 0

…并且没有额外的输出。这是因为
printf
语句的输出是缓冲的,并且对指定管道的写入是阻塞的,因此输出永远不会被刷新。向printf添加
\n
可能会像您期望的那样显示它。

作为旁白,无论是
gdb
还是
strace
都是一个很好的选择用于精确计算代码挂起位置的工具。当程序自行运行时,您的第一个输出是我所期望的。根据您所说的,当程序自行运行时以及从父程序执行fork时,它会阻止写入管道。这可能是因为父程序完成时我没有正确移除管道吗s所以我正在尝试访问旧管道?我当前正在使用unlink()。还将查看
gdb
strace
,为指出它们而欢呼。放弃第二个问题,我们刚刚在管道上重新阅读了man文件,为指向正确方向的指针而欢呼。如果有人读过这个问题…我对管道的写入被阻塞,因为我正在管道上执行写入和读取操作管道是分开的,而不是同时进行的。一旦我删除了
wait()
从父程序开始,一切都按预期进行。另外,无论是
gdb
还是
strace
都是一个很好的工具,可以准确地确定代码挂起的位置。当程序独立运行时,您的第一个输出就是我所期望的。根据您所说的,当程序独立运行时,它会阻止对管道的写入当fork从父程序执行时。这可能是因为父程序完成时我没有正确移除管道,所以我尝试访问旧管道吗?我当前使用的是unlink()。还将查看
gdb
strace
,为指出它们而欢呼。放弃第二个问题,我们刚刚在管道上重新阅读了man文件,为指向正确方向的指针而欢呼。如果有人读过这个问题…我对管道的写入被阻塞,因为我正在管道上执行写入和读取操作管道是分开的,而不是同时进行的。一旦我删除了
wait()
从父程序开始,一切都按预期进行。是的,当此程序从另一个进程执行fork时。但是,如果程序自己运行且管道不存在,则当此程序从另一个进程执行fork时,程序仍应优雅地退出,说明管道没有在larsks的MachineEyes上使用。But如果程序是独立运行的,并且管道不存在,那么程序仍然应该优雅地退出,说管道没有在larsks的机器上使用