Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/25.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
can';第一次进入do while后无法获取输入_C_Linux_String - Fatal编程技术网

can';第一次进入do while后无法获取输入

can';第一次进入do while后无法获取输入,c,linux,string,C,Linux,String,我正在尝试分叉一个子进程,每当用户输入一行文本以打印输入的行数时,将其置于睡眠状态并将其唤醒 我的代码运行良好。但奇怪的是,我发现我必须使用两个get(str)语句,如果我没有这样做,用户只会被提示一次 如果运行代码并注释one get(str),您将知道我的意思 谢谢你的帮助。谢谢 #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <wait.h> #in

我正在尝试分叉一个子进程,每当用户输入一行文本以打印输入的行数时,将其置于睡眠状态并将其唤醒

我的代码运行良好。但奇怪的是,我发现我必须使用两个get(str)语句,如果我没有这样做,用户只会被提示一次

如果运行代码并注释one get(str),您将知道我的意思

谢谢你的帮助。谢谢

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <wait.h>
#include <unistd.h>
#include <signal.h>

main () {
    int n;
    char ch;
    pid_t child;
    int erret;
    char str[20];
    int c = 0;

    if ((child = fork ()) < 0) {
        perror ("fork");
        exit (0);
    }

    else {
        //waitpid(child,NULL,0);
        do {
            waitpid (child, NULL, 0);
            printf ("Enter a line(s) \n");
            //funn();
            //fflush(stdin);
            //scanf("%d",&n);
            gets (str);
            gets (str);
            erret = kill (child, SIGCHLD);
            printf ("Signal %d\n", erret);
            if (erret >= 0) {
                c++;
                printf ("You have entered : %d line(s)\n", c);
                //pause();
                //waitpid(child,NULL,0);
            }

            else {
                kill (child, SIGKILL);
                exit (0);

            }
            printf ("\nPress 9 to exit  :");
            fflush (stdin);
            scanf ("%d", &n);
            fflush (stdin);
        } while (n != 9);
        kill (child, SIGKILL);
    }
}
#包括
#包括
#包括
#包括
#包括
#包括
主要(){
int n;
char ch;
pid_t儿童;
INTERRET;
char-str[20];
int c=0;
如果((child=fork())<0){
佩罗尔(“福克”);
出口(0);
}
否则{
//waitpid(子级,NULL,0);
做{
waitpid(子级,NULL,0);
printf(“输入一行)\n”);
//funn();
//fflush(stdin);
//scanf(“%d”和“&n”);
获取(str);
获取(str);
erret=kill(child,SIGCHLD);
printf(“信号%d\n”,erret);
如果(erret>=0){
C++;
printf(“您已经输入了%d行)\n”,c);
//暂停();
//waitpid(子级,NULL,0);
}
否则{
杀死(孩子,SIGKILL);
出口(0);
}
printf(“\n按9退出:”;
fflush(stdin);
scanf(“%d”和“&n”);
fflush(stdin);
}而(n!=9);
杀死(孩子,SIGKILL);
}
}

在您尝试输入时,有许多方法可以获得重复的字符串输入。标准方法之一是收集输入,直到用户发出信号表示没有更多数据可输入。(在Linux上,
EOF
由终端使用
ctrl+d
生成)。在不更改逻辑和不评论
fork、waitpid等实现的情况下,
以下是一种处理为程序收集字符串输入的方法,直到用户通过按键盘上的
ctrl+d
发送
EOF

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <wait.h>
#include <unistd.h>
#include <signal.h>

int main () {

    pid_t child;
    int erret;
    int c = 0;

    ssize_t nread = 0;          /* number of chars read by getline  */
    char *lineptr = NULL;       /* string read by (NULL forces getline to allocate) */
    size_t nbytes = 0;          /* number of bytes to read (ignored with lineptr = NULL) */

    if ((child = fork ()) < 0) {
        perror ("fork");
        exit (0);
    }
    else
    {
        waitpid (child, NULL, 0);
        printf ("\nEnter line(s) of text (ctrl+d to exit):\n\n");

        while (printf ("  Input: ") && (nread = getline (&lineptr, &nbytes, stdin) != -1)) 
        {
            erret = kill (child, SIGCHLD);
            printf ("\n  Signal %d\n", erret);

            if (erret >= 0) {
                c++;
                printf ("  You have entered : %d line(s)\n\n", c);
            }
            else
            {
                kill (child, SIGKILL);
                exit (0);
            }
        }

        kill (child, SIGKILL);
    }

    return 0;
}

你的概念是有缺陷的,你没有明确说明巴拉特和孩子做了什么。因此,您在
获取
时有一个竞赛条件。这是因为在
fork
调用之后,运行了两个代码副本,一个由父级复制,一个由子级复制。因此,解决方法是添加一个
swich
else if
语句,将代码分为子代码段和父代码段。顺便说一句,如前所述,使用
fgets

switch(fork()):
    case -1:
        //Error
    case 0:
        // Child code
    default:
        // Parant code

编写代码时有一定的标准级别。更具体地说,缩进帮助人们更有效地阅读代码。不要使用
get
它不再是C标准的一部分。使用
fgets
或(更好)
getline
(是的,它在
stdin
上工作。fflush(stdin)不会清理输入缓冲区。此外,
gets
容易发生缓冲区溢出。希望这不是接受标准输入的任意用户输入的网络程序的一部分。
switch(fork()):
    case -1:
        //Error
    case 0:
        // Child code
    default:
        // Parant code