Использование функции fork после получения пользовательского ввода
Как заставить работать функцию fork после получения пользовательского ввода от функции fgets() и получения токенов от пользовательского ввода?
Мой код:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <errno.h>
/* the line can have at most 2000 words*/
void tokeniseLine(char *Line, char **Words, int *Wordn);
/* break line into words separated by whitespace, placing them in the
array words, and setting the count to Wordn */
void search&execute();
int main()
{
char Line[4000], *Words[2000], string[4000];
int Stops=0,Wordn=0;
char *end = "exit";
while(1)
{
printf("Enter program: ");
fgets(Line, 4000, stdin ); /* read a line of text here */
/* use of exitting begins when user enters 'exit' or when the program finally locates/can't locate the user's requested file*/
if ( strcmp(Line, end) == 0 ){
exit(0);
}
else
if ( strcmp(Line, end) != 0 ) {
printf("file successfully found.");
tokeniseLine(Line,Words,&Wordn);
search&execute();//using fork function to make process
}
return 0;
}
void tokeniseLine(char *Line, char **Words, int *Wordn)
{
char *token;
/* get the first token */
token = strtok(Line, " \t\n");
/* walk through other tokens */
while( token != NULL )
{
token = strtok(NULL, " \t\n");
}
return;
}
void search&execute()//this is the function which I wanted to work last after the user input is tokenised
{
pid_t childpid; /* variable to store the child's pid */
int retval; /* child process: user-provided return code */
int status; /* parent process: child's exit status */
/* only 1 int variable is needed because each process would have its
own instance of the variable
here, 2 int variables are used for clarity */
/* now create new process */
childpid = fork();
if (childpid >= 0) /* fork succeeded */
{
if (childpid == 0) /* fork() returns 0 to the child process */
{
printf("CHILD: I am the child process!\n");
printf("CHILD: Here's my PID: %d\n", getpid());
printf("CHILD: My parent's PID is: %d\n", getppid());
printf("CHILD: The value of my copy of childpid is: %d\n",childpid);
printf("CHILD: Sleeping for 1 second...\n");
sleep(1); /* sleep for 1 second */
printf("CHILD: Enter an exit value (0 to 255): ");
scanf(" %d", &retval);
printf("CHILD: Goodbye!\n");
exit(retval); /* child exits with user-provided return code */
}
else /* fork() returns new pid to the parent process */
{
printf("PARENT: I am the parent process!\n");
printf("PARENT: Here's my PID: %d\n", getpid());
printf("PARENT: The value of my copy of childpid is %d\n",childpid);
printf("PARENT: I will now wait for my child to exit.\n");
wait(&status); /* wait for child to exit, and store its status */
printf("PARENT: Child's exit code is: %d\n", WEXITSTATUS(status));
printf("PARENT: Goodbye!\n");
exit(0); /* parent exits */
}
}
else /* fork returns -1 on failure */
{
perror("fork"); /* display error message */
exit(0);
}
}
Я пытался получить функцию fork для возврата значения fork, но она не работала, когда я пытался добавить пользовательский ввод. Как вы это исправите?
1 ответ
Когда различные проблемы, указанные в комментариях выше, исправлены, оказывается большое количество неиспользуемых переменных и неиспользуемых параметров функции. Очистить это, и обеспечить printf()
форматы заканчиваются символом новой строки, приводят к такому коду:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
void tokeniseLine(char *Line);
void search_execute(void);
int main(void)
{
char Line[4000];
char *end = "exit";
while (1)
{
printf("Enter program: ");
fgets(Line, 4000, stdin );
if (strcmp(Line, end) == 0)
{
exit(0);
}
else if (strcmp(Line, end) != 0)
{
printf("file successfully found.\n");
tokeniseLine(Line);
search_execute();
}
}
return 0;
}
void tokeniseLine(char *Line)
{
char *token;
token = strtok(Line, " \t\n");
while (token != NULL)
{
printf("Token: [%s]\n", token);
token = strtok(NULL, " \t\n");
}
}
void search_execute(void)
{
pid_t childpid;
int retval;
int status;
childpid = fork();
if (childpid >= 0)
{
if (childpid == 0)
{
printf("CHILD: I am the child process!\n");
printf("CHILD: Here's my PID: %d\n", getpid());
printf("CHILD: My parent's PID is: %d\n", getppid());
printf("CHILD: The value of my copy of childpid is: %d\n", childpid);
printf("CHILD: Sleeping for 1 second...\n");
sleep(1);
printf("CHILD: Enter an exit value (0 to 255): ");
scanf(" %d", &retval);
printf("CHILD: Goodbye!\n");
exit(retval);
}
else
{
printf("PARENT: I am the parent process!\n");
printf("PARENT: Here's my PID: %d\n", getpid());
printf("PARENT: The value of my copy of childpid is %d\n", childpid);
printf("PARENT: I will now wait for my child to exit.\n");
wait(&status);
printf("PARENT: Child's exit code is: %d\n", WEXITSTATUS(status));
printf("PARENT: Goodbye!\n");
exit(0);
}
}
else
{
perror("fork");
exit(0);
}
}
Цикл в main()
является поддельным; первый звонок search_execute()
имеет код выхода на всех путях кода, поэтому цикл в main()
никогда не повторяется else if (strcmp(Line, end) != 0)
на самом деле не нужно if
часть; если предыдущий if
не удалось, код окажется в блоке после else
,
Компиляция:
Исходный файл был назван x19.c
:
$ gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
> -Wold-style-definition -Werror x19.c -o x19
$
Образец вывода:
$ ./x19
Enter program: periodic table
file successfully found.
Token: [periodic]
Token: [table]
PARENT: I am the parent process!
PARENT: Here's my PID: 4142
PARENT: The value of my copy of childpid is 4143
PARENT: I will now wait for my child to exit.
CHILD: I am the child process!
CHILD: Here's my PID: 4143
CHILD: My parent's PID is: 4142
CHILD: The value of my copy of childpid is: 0
CHILD: Sleeping for 1 second...
CHILD: Enter an exit value (0 to 255): 47
CHILD: Goodbye!
PARENT: Child's exit code is: 47
PARENT: Goodbye!
$
По сути, кажется, что код работает более или менее разумно, и никаких существенных изменений не произошло. Есть некоторые улучшения, которые можно сделать. Если проблема не устранена, вам нужно более четко показать, какие проблемы вы видите.