Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.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中的管道将术语写入bc_C_Pipe_Bc - Fatal编程技术网

通过C中的管道将术语写入bc

通过C中的管道将术语写入bc,c,pipe,bc,C,Pipe,Bc,我在这个C练习中遇到了一个问题。 任务是创建两个进程。两者通过两个管道连接,这两个管道终止于子对象的标准输入和标准输出。然后用bc替换子进程。 然后我应该写一个从父进程到子进程(bc)的术语(例如1+2) 管道正在做他们应该做的事情,然而,bc似乎不喜欢输入。当我向管道中写入时,bc用以下多行响应: (standard_in) 1: illegal character: ^@ 这是我目前的解决方案: #include <stdio.h> #include <string.h&

我在这个C练习中遇到了一个问题。 任务是创建两个进程。两者通过两个管道连接,这两个管道终止于子对象的标准输入和标准输出。然后用bc替换子进程。 然后我应该写一个从父进程到子进程(bc)的术语(例如1+2)

管道正在做他们应该做的事情,然而,bc似乎不喜欢输入。当我向管道中写入时,bc用以下多行响应:

(standard_in) 1: illegal character: ^@
这是我目前的解决方案:

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

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

    /*Create two pipes:
        One from parent to child (pipe_pc)
        and one from child to parent (pipe_cp).
    */
    int pipe_pc[2], pipe_cp[2];

    int cid;

    if (pipe(pipe_pc) == -1 || pipe(pipe_cp) == -1) {
        printf("Could not pipe\n");
        exit(EXIT_FAILURE);
    }

    // Create child process
    cid = fork();

    if (cid == -1) {
        printf("Could not fork.\n");
        exit(EXIT_FAILURE);
    }

    // Child process
    if (cid == 0) {

        // Redirect pipes
        close(STDOUT_FILENO);
        close(STDIN_FILENO);
        close(pipe_pc[1]); // Close writing end
        close(pipe_cp[0]); // Close reading end

        dup2(pipe_pc[0], STDIN_FILENO); // Take stdin from parent
        dup2(pipe_cp[1], STDOUT_FILENO); // Give stdout to parent

        int err;

        // Replace child with bc
        err = execl("/usr/bin/bc", "bc --quiet", (char*) NULL);

        printf("%s %d\n", "Could not start bc:", err);
        exit(err);
    }

    // Parent Process
    else {

        char input[128] = "";
        char buffer[128] = "";

        printf("%s\n", "Parent process running");

        // Copy argv to a single string
        for(int i=1; i < argc; i++) {
            strcat(input, argv[i]);
        }

        // Write the input to the child's stdin
        write(pipe_pc[1], input, sizeof(input);

        // Read the child's stdout
        read(pipe_cp[0], buffer, sizeof(buffer));

        printf("Result: %s\n", buffer);

        return 0;
    }

}
#包括
#包括
#包括
#包括
int main(int argc,char*argv[]){
/*创建两个管道:
一个从父级到子级(管道和pc)
和一个从子级到父级(pipe_cp)。
*/
int pipe_pc[2],pipe_cp[2];
int-cid;
如果(管道(管道pc)=-1 | |管道(管道cp)=-1){
printf(“无法通过管道\n”);
退出(退出失败);
}
//创建子进程
cid=fork();
如果(cid==-1){
printf(“无法分叉。\n”);
退出(退出失败);
}
//子进程
如果(cid==0){
//重定向管道
关闭(标准文件号);
关闭(标准文件号);
关闭(pipe_pc[1]);//关闭写入端
关闭(管道[0]);//关闭读取端
dup2(管道[0],标准输入文件号);//从父级获取标准输入文件
dup2(pipe_cp[1],标准输出文件号);//将标准输出给父级
INTERR;
//用bc替换child
err=execl(“/usr/bin/bc”,“bc--quiet”,“char*)NULL);
printf(“%s%d\n”,“无法启动bc:”,错误);
退出(err);
}
//父进程
否则{
字符输入[128]=“”;
字符缓冲区[128]=“”;
printf(“%s\n”,“父进程正在运行”);
//将argv复制到单个字符串
对于(int i=1;i

非常感谢您的提示和帮助,提前感谢!

您的代码有许多未定义的行为


您可以编写所有输入数组。但只需编写使用strcat()复制的内容。
。 使用strlen

write(pipe_pc[1], input, strlen(input));

在这里,您应该验证您没有超过128个八位字节

if (strlen(input) + strlen(argv[i]) + 1 > 128) {
  break;
}
strcat(input, argv[i]);

这里不验证缓冲区是否是有效的c字符串

ssize_t ret = read(pipe_cp[0], buffer, sizeof(buffer) - 1);
if (ret < 0)
  return 1;
buffer[ret] = '\0';
读/写之后

close(pipe_pc[1]);
close(pipe_cp[0]);

在执行
dup2()


你不需要在dup2之前关闭你的旧fd,他会为你做。你也不需要检查
dup2()的错误

你的代码有很多未定义的行为


您可以编写所有输入数组。但只需编写使用strcat()复制的内容。
。 使用strlen

write(pipe_pc[1], input, strlen(input));

在这里,您应该验证您没有超过128个八位字节

if (strlen(input) + strlen(argv[i]) + 1 > 128) {
  break;
}
strcat(input, argv[i]);

这里不验证缓冲区是否是有效的c字符串

ssize_t ret = read(pipe_cp[0], buffer, sizeof(buffer) - 1);
if (ret < 0)
  return 1;
buffer[ret] = '\0';
读/写之后

close(pipe_pc[1]);
close(pipe_cp[0]);

在执行
dup2()


在dup2之前,您不需要关闭旧的fd,他会为您执行此操作。并且您不检查
dup2()的错误

问题是您在管道中的写入不正确,因此bc收到了错误的输入

我重写了
else
分支

如果不确定在管道中发送的内容,请临时将管道描述符替换为0(i/o fd),并目视检查所做的操作

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

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

    /* Create two pipes: One from parent to child (pipe_pc) and one
       from child to parent (pipe_cp).
    */
    int pipe_pc[2], pipe_cp[2];

    int cid;

    if (pipe(pipe_pc) == -1 || pipe(pipe_cp) == -1) {
        printf("Could not pipe\n");
        exit(EXIT_FAILURE);
    }

    // Create child process
    cid = fork();

    if (cid == -1) {
        printf("Could not fork.\n");
        exit(EXIT_FAILURE);
    }

    // Child process
    if (cid == 0) {

        // Redirect pipes
        close(STDOUT_FILENO);
        close(STDIN_FILENO);
        close(pipe_pc[1]); // Close writing end
        close(pipe_cp[0]); // Close reading end

        dup2(pipe_pc[0], STDIN_FILENO); // Take stdin from parent
        dup2(pipe_cp[1], STDOUT_FILENO); // Give stdout to parent

        int err;

        // Replace child with bc
        err = execl("/usr/bin/bc", "bc --quiet", (char*) NULL);

        printf("%s %d\n", "Could not start bc:", err);
        exit(err);
    }

    // Parent Process
    else {
        char buffer[128] = "";

        // printf("%s\n", "Parent process running");

        for(int i=1; i < argc; i++)
            write(pipe_pc[1], argv[i], strlen(argv[i]));

        write(pipe_pc[1], "\n", 1);

        read(pipe_cp[0], buffer, sizeof(buffer));

        printf("Result: %s\n", buffer);

        return 0;
    }

}
#包括
#包括
#包括
#包括
int main(int argc,char*argv[]){
/*创建两个管道:一个从父管道到子管道(管道)和一个
从子级到父级(管道)。
*/
int pipe_pc[2],pipe_cp[2];
int-cid;
如果(管道(管道pc)=-1 | |管道(管道cp)=-1){
printf(“无法通过管道\n”);
退出(退出失败);
}
//创建子进程
cid=fork();
如果(cid==-1){
printf(“无法分叉。\n”);
退出(退出失败);
}
//子进程
如果(cid==0){
//重定向管道
关闭(标准文件号);
关闭(标准文件号);
关闭(pipe_pc[1]);//关闭写入端
关闭(管道[0]);//关闭读取端
dup2(管道[0],标准输入文件号);//从父级获取标准输入文件
dup2(pipe_cp[1],标准输出文件号);//将标准输出给父级
INTERR;
//用bc替换child
err=execl(“/usr/bin/bc”,“bc--quiet”,“char*)NULL);
printf(“%s%d\n”,“无法启动bc:”,错误);
退出(err);
}
//父进程
否则{
字符缓冲区[128]=“”;
//printf(“%s\n”,“父进程正在运行”);
对于(int i=1;i
问题在于您没有在管道中正确写入,因此bc收到了错误的输入

我重写了
else
分支

如果不确定在管道中发送的内容,请临时将管道描述符替换为0(i/o fd),并目视检查所做的操作

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

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

    /* Create two pipes: One from parent to child (pipe_pc) and one
       from child to parent (pipe_cp).
    */
    int pipe_pc[2], pipe_cp[2];

    int cid;

    if (pipe(pipe_pc) == -1 || pipe(pipe_cp) == -1) {
        printf("Could not pipe\n");
        exit(EXIT_FAILURE);
    }

    // Create child process
    cid = fork();

    if (cid == -1) {
        printf("Could not fork.\n");
        exit(EXIT_FAILURE);
    }

    // Child process
    if (cid == 0) {

        // Redirect pipes
        close(STDOUT_FILENO);
        close(STDIN_FILENO);
        close(pipe_pc[1]); // Close writing end
        close(pipe_cp[0]); // Close reading end

        dup2(pipe_pc[0], STDIN_FILENO); // Take stdin from parent
        dup2(pipe_cp[1], STDOUT_FILENO); // Give stdout to parent

        int err;

        // Replace child with bc
        err = execl("/usr/bin/bc", "bc --quiet", (char*) NULL);

        printf("%s %d\n", "Could not start bc:", err);
        exit(err);
    }

    // Parent Process
    else {
        char buffer[128] = "";

        // printf("%s\n", "Parent process running");

        for(int i=1; i < argc; i++)
            write(pipe_pc[1], argv[i], strlen(argv[i]));

        write(pipe_pc[1], "\n", 1);

        read(pipe_cp[0], buffer, sizeof(buffer));

        printf("Result: %s\n", buffer);

        return 0;
    }

}
#包括
#包括
#包括
#包括
int main(int argc,char*argv[]){
/*创建两个管道:一个从父管道到子管道(管道)和一个
从子级到父级(管道)。
*/
int pipe_pc[2],pipe_cp[2];
int-cid;
如果(管道(管道pc)=-1 | |管道(管道cp)=-1){
printf(“无法通过管道\n”);
退出(退出失败);
}
//创建子进程
cid=fork();
如果(cid==-1){
printf(“无法分叉。\n”);
退出(退出失败);
}
//子进程
如果(cid==0){
//重定向管道
关闭(标准文件号);
关闭(标准文件号);
关闭(pipe_pc[1]);//关闭写入端
关闭(管道[0]);//关闭读取端
D