第一次做完之后无法获得输入

时间:2014-10-15 00:14:25

标签: c linux string

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

我的代码工作正常。但我发现奇怪的是我必须使用两个gets(str)语句,如果我没有提示用户只会被提示一次。

如果运行代码和评论得到(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);
    }
}

2 个答案:

答案 0 :(得分:1)

你的概念是有缺陷的,你没有明确指出父亲和孩子的所作所为。所以你在gets上有种族条件。这是因为在fork调用之后运行了两个代码副本,父代一个副本,子代表一个副本。因此,修复方法是添加swichelse if语句,将代码分隔为子级和父级的部分。 BTW已如上所述使用fgets

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

答案 1 :(得分:0)

您可以通过多种方式获得重复的字符串输入。标准方法之一是收集输入,直到用户发出信号EOF表示没有更多数据要输入。 (在Linux上EOF从终端生成ctrl + d)。在不更改逻辑且未评论fork, waitpid, etc..实施的情况下,以下是处理收集程序字符串输入的一种方法,直到用户通过按键盘上的EOF发送ctrl+d为止:

#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;
}

<强>输出:

$ ./bin/ind2

Enter line(s) of text (ctrl+d to exit):

  Input: line one

  Signal 0
  You have entered : 1 line(s)

  Input: line 2

  Signal 0
  You have entered : 2 line(s)

  Input: line 3

  Signal 0
  You have entered : 3 line(s)

  Input: Killed