Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.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 - Fatal编程技术网

两个C程序相互作用,玩猜谜游戏

两个C程序相互作用,玩猜谜游戏,c,C,所以,在我的课堂上,我应该首先创建一个猜测游戏,从用户那里获取输入,并根据他们的名字,告诉他们是否接近魔法数字。这是我的程序 #include <stdio.h> #include <string.h> typedef struct { //user info. stores name and number from file input. char list_name[20]; int list_num; }list; char user_name[20]; //

所以,在我的课堂上,我应该首先创建一个猜测游戏,从用户那里获取输入,并根据他们的名字,告诉他们是否接近魔法数字。这是我的程序

#include <stdio.h>
#include <string.h>

typedef struct { //user info. stores name and number from file input.
char list_name[20];
int list_num;
}list;

char user_name[20]; // info scanned in from user playing the game.
int user_magic_num; // "

int main(){

FILE *fp;
int i; // for the for loop.
list answers;
int matched = 0;

fp = fopen("answers.txt", "rb");
if(fp == NULL)
{
  perror("Error opening file");
  return -1;
}

inquiry();

for (i=0; i<3; i++)
{
    fscanf (fp, "%s %d", answers.list_name, &answers.list_num);
    if(feof(fp))
    {
       puts("End of file.");
       break;
    }

    if (strcmp(answers.list_name,user_name)==0)//User is recognized.
    {
        matched = 1;
        if(user_magic_num==answers.list_num)
        {
            printf("\n Yes, %s. You guess correctly! %d is the magic 
number!\n",user_name, answers.list_num);
            break;
        }
        else if(user_magic_num>answers.list_num)
        {
            printf("\n No, that's too high.\n");
        }
        else
        {
            printf("\n No, that's too low.\n");
        }
    }
}
if (!matched)
{
    answers.list_num = 12345;
    printf ("\n User not recognized. Default magic number set.\n\n");

     if(user_magic_num==answers.list_num)
        {
            printf("\n You guess correctly! %d is the magic number!\n", 
answers.list_num);
        }
        else if(user_magic_num>answers.list_num)
        {
            printf("\n No, that's too high.\n");
        }
        else
        {
            printf("\n No, that's too low.\n");
        }
}
  return 0;
}

void inquiry()
{
printf("\n Hi, what's your name? \n \n");
scanf("%s",user_name);
printf("\n Hello, %s! \n \n What's the magic number? \n \n",user_name);
scanf("%d", &user_magic_num);
printf("\n You guessed %d.\n\n", user_magic_num);
}
如果您的程序收到的输入字符串不是问题中描述的提示 2以上,它应该用三个问号(??)回答,然后退出。例如:

 *What is your name?**
 **Bob**
 *Do you like apples?*
 **???

说明中还说要将其作为一个.c文件提交,但我不完全确定在不使用头文件的情况下如何做到这一点?非常感谢任何帮助或提示。

这里您需要两个进程之间的进程间通信。进程间通信有很多选项。但对于您的要求,最简单的方法是排队。创建两个队列,例如
question_q
answer_q
(检查如何在
unix
中创建队列,以及如何读取队列以及如何将消息放入队列)。现在,您的上述程序将把问题放在
question_q
中,该问题将由响应上述过程中每个问题的其他过程读取,并将答案作为
Bob
放在
answer_q
中,您的另一个过程将再次读取该问题。我认为这将对您有所帮助。

正如Jonathan Leffler所评论的,您需要两个管道:一个用于读取程序stdout,另一个用于写入其stdin

下面是一个小例子:

程序.c

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv){
    char name[20];
    int number;

    //Ask
    printf("Hi, what is your name?\n");
    fflush(stdout);
    //Get user input
    scanf("%19s", name);
    //Ask
    printf("What is the magic number?\n");
    fflush(stdout);
    //Get user input
    scanf("%d", &number);

    printf("Thanks!\n");
    fflush(stdout);
    printf("\nYour name is %s and the magic number is %d!\n", name, number);
    fflush(stdout);

    return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <string.h>

int main(int argc, char **argv){

    //A pipe to read the program output
    int output_pipe[2];
    //A pipe to send input to the program
    int input_pipe[2];
    //For the fork/exec
    pid_t pid;

    //To read the program output
    char process_line[4096];

    //Create pipes
    if(pipe(output_pipe) == -1){
        printf("Failed on pipe();\n");
        exit(1);
    } else if(pipe(input_pipe) == -1){
        printf("Failed on pipe();\n");
        exit(1);
    }

    //Fork the process
    pid = fork();

    if(pid == -1){
        printf("Failed on fork();\n");
        exit(1);
    } else if(pid == 0){
        //CHILD PROCESS

        //We duplicate the writing end of the output pipe to have the same file descriptor number as the process stdout, so everything it writes to stdout will be sent to the reading side of the pipe (output_pipe[0])
        dup2(output_pipe[1], STDOUT_FILENO);
        //Now that the output is redirected we can close the pipes
        close(output_pipe[1]);
        close(output_pipe[0]);

        //We duplicate the reading end of the input pipe to have the same file descriptor number as the process stdin, so everything that is written to the other end of the pipe (input_pipe[1]) will be sent to the process stdin.
        dup2(input_pipe[0], STDIN_FILENO);
        //Now that the input is redirected we can close the pipes
        close(input_pipe[1]);
        close(input_pipe[0]);

        //Exec
        execl("./program", "./program", NULL);

        //In case exec fails
        printf("Failed to execute program!\n");
        exit(1);
    } else {
        //PARENT PROCESS

        int read_bytes;

        //Read from the pipe that is now the child process stdout
        while((read_bytes = read(output_pipe[0], process_line, sizeof(process_line))) > 0){
            //Check what was read and respond accordingly
            printf("[PROGRAM OUTPUT]: %.*s", read_bytes, process_line);
            if(strcmp(process_line, "Hi, what is your name?\n") == 0){
                printf("[ANSWER]: Mike\n");
                write(input_pipe[1], "Mike\n", 5);
            } else if (strcmp(process_line, "What is the magic number?\n") == 0){
                printf("[ANSWER]: 41\n");
                write(input_pipe[1], "41\n", 3);
            } else {
                if(strcmp(process_line, "Thanks!\n") == 0){
                    printf("You're welcome!\n");
                } else if(strcmp(process_line, "\nYour name is Mike and the magic number is 41!\n") == 0){
                    printf("Done!\n");
                    break;
                } else {
                    printf("???\n");
                }
            }
            //Clears the process line
            memset(process_line, 0, sizeof(process_line));
        }

        //Close the pipes
        close(input_pipe[1]);
        close(input_pipe[0]);
        close(output_pipe[1]);
        close(output_pipe[0]);

        printf("Waiting child process!\n");
        wait(NULL);
    }
    return 0;
}
这有点简单,也许您必须更改代码以满足您的需要,但这是一个如何使用管道读取程序stdout并写入其stdin的示例

首先创建两个管道(它们是单向的,因此需要一个用于stdout,另一个用于stdin),使用
fork
创建子进程,复制管道以获得stdin和stdout的文件描述符编号(记住将管道的写入端放在stdout上,将管道的读取端放在stdin上)并执行程序本身,而在父进程上,您只需使用
read
write
系统调用,使用这些管道的另一端读取程序输出并写入其输入


如果您不熟悉
fork
exec
pipe
dup2
,一开始可能有点难以理解,但希望这些注释能帮助您理解代码(不要忘了阅读
手册页
).

可能,您需要两个管道和一个分叉。您创建管道;您分叉孩子。您可以决定家长是否提问,孩子是否回答(可能)反之亦然。我将假设父对象提问,子对象回答。您将装配东西,以便子对象的标准输入来自一个管道,而子对象的标准输出流向另一个管道(确保关闭子对象中未复制的管道描述符)。家长需要将其问题发送给孩子和终端,并需要回显孩子的回答。请确保您知道合奏将如何结束。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <string.h>

int main(int argc, char **argv){

    //A pipe to read the program output
    int output_pipe[2];
    //A pipe to send input to the program
    int input_pipe[2];
    //For the fork/exec
    pid_t pid;

    //To read the program output
    char process_line[4096];

    //Create pipes
    if(pipe(output_pipe) == -1){
        printf("Failed on pipe();\n");
        exit(1);
    } else if(pipe(input_pipe) == -1){
        printf("Failed on pipe();\n");
        exit(1);
    }

    //Fork the process
    pid = fork();

    if(pid == -1){
        printf("Failed on fork();\n");
        exit(1);
    } else if(pid == 0){
        //CHILD PROCESS

        //We duplicate the writing end of the output pipe to have the same file descriptor number as the process stdout, so everything it writes to stdout will be sent to the reading side of the pipe (output_pipe[0])
        dup2(output_pipe[1], STDOUT_FILENO);
        //Now that the output is redirected we can close the pipes
        close(output_pipe[1]);
        close(output_pipe[0]);

        //We duplicate the reading end of the input pipe to have the same file descriptor number as the process stdin, so everything that is written to the other end of the pipe (input_pipe[1]) will be sent to the process stdin.
        dup2(input_pipe[0], STDIN_FILENO);
        //Now that the input is redirected we can close the pipes
        close(input_pipe[1]);
        close(input_pipe[0]);

        //Exec
        execl("./program", "./program", NULL);

        //In case exec fails
        printf("Failed to execute program!\n");
        exit(1);
    } else {
        //PARENT PROCESS

        int read_bytes;

        //Read from the pipe that is now the child process stdout
        while((read_bytes = read(output_pipe[0], process_line, sizeof(process_line))) > 0){
            //Check what was read and respond accordingly
            printf("[PROGRAM OUTPUT]: %.*s", read_bytes, process_line);
            if(strcmp(process_line, "Hi, what is your name?\n") == 0){
                printf("[ANSWER]: Mike\n");
                write(input_pipe[1], "Mike\n", 5);
            } else if (strcmp(process_line, "What is the magic number?\n") == 0){
                printf("[ANSWER]: 41\n");
                write(input_pipe[1], "41\n", 3);
            } else {
                if(strcmp(process_line, "Thanks!\n") == 0){
                    printf("You're welcome!\n");
                } else if(strcmp(process_line, "\nYour name is Mike and the magic number is 41!\n") == 0){
                    printf("Done!\n");
                    break;
                } else {
                    printf("???\n");
                }
            }
            //Clears the process line
            memset(process_line, 0, sizeof(process_line));
        }

        //Close the pipes
        close(input_pipe[1]);
        close(input_pipe[0]);
        close(output_pipe[1]);
        close(output_pipe[0]);

        printf("Waiting child process!\n");
        wait(NULL);
    }
    return 0;
}