gpt4 book ai didi

c - 学习管道和流程

转载 作者:行者123 更新时间:2023-12-04 12:09:05 26 4
gpt4 key购买 nike

我正在尝试更好地了解管道和流程。我想实现多个链式管道,例如 cat test.txt |排序 | uniq -c。我用 cat test.txt 开始我的代码,但它不工作。它可以编译,但是当我在命令行中提供文件名时,例如 ./hwk ./test.txt。没有返回。有人可以看一下并给我一些提示吗?我想使用循环,因为我希望能够添加更多管道。我知道我的代码中有很多问题,所以我希望有人能给我一些关于这个主题的指导。谢谢。

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

#define SIZE 1024

int main (int argc, char **argv)
{
int num_pipe = 1;
int commands = num_pipe + 1; //number of commands is one more than the number of pipes
int fds[num_pipe * 2];

int status;
pid_t pid;
char *str_ptr;

//Pass Command
char *arrayOfCommands[] = {"cat", NULL};


//Setting up pipes
int i;
for (i = 0; i < num_pipe; i++){
if(pipe(fds + i * 2) == -1) {
perror("Error creating pipes");
exit(1);
}
}

int j = 0;
for (i = 0; i < commands - 1; ++i) {
pid = fork();

if (pid == 0) {
if (i < commands) {
if (dup2(fds[j+1], 1) < 0) {
perror("dup2 error");
exit(EXIT_FAILURE);
}
}

if (j != 0) {
if(dup2(fds[j-2], 0) < 0) {
perror("dup2 error");
exit(EXIT_FAILURE);
}
}

for (i = 0; i < 2*num_pipe; i++) {
close(fds[i]);
}


if (execvp(arrayOfCommands[0], arrayOfCommands) < 0) {
perror("Array error");
exit(EXIT_FAILURE);
}


}
else if (pid < 0){
perror("Error");
exit(EXIT_FAILURE);
}

j += 2;
}

for (i = 0; i < 2 * num_pipe; i++){
close(fds[i]);
}

for (i = 0; i < num_pipe + 1; i++) {
wait(&status);
}


return 0;
}

最佳答案

我将此主要是对您的程序进行了较小的改编称为 p3.c,编译它以生成 p3。由于只有一个命令 (cat) 被调用,因此我进行了一些调整以使其能够正常工作。当作为./p3 p3.c运行时,它会打印出源代码的内容。

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

static void err_exit(const char *str);

int main (int argc, char **argv)
{
int num_pipe = 0; // Just cat - no pipes
int commands = num_pipe + 1; // Number of commands is one more than the number of pipes
int fds[num_pipe * 2 + 1]; // Avoid size 0 array
char *arrayOfCommands[3] = { "cat", NULL, NULL};

if (argc != 2)
err_exit("Missing filename argument");
arrayOfCommands[1] = argv[1];

for (int i = 0; i < num_pipe; i++)
{
if (pipe(fds + i * 2) == -1)
err_exit("Error creating pipes");
}

int j = 0;
for (int i = 0; i < commands; ++i)
{
pid_t pid = fork();

if (pid == 0)
{
printf("%d: %s %s\n", (int)getpid(), arrayOfCommands[0], arrayOfCommands[1]);
fflush(stdout);
if (i < commands-1 && dup2(fds[j+1], 1) < 0)
err_exit("dup2 error");
if (j != 0 && dup2(fds[j-2], 0) < 0)
err_exit("dup2 error");
for (i = 0; i < 2*num_pipe; i++)
close(fds[i]);

execvp(arrayOfCommands[0], arrayOfCommands);
err_exit("Array error");
}
else if (pid < 0)
err_exit("Error");

j += 2;
}

for (int i = 0; i < 2 * num_pipe; i++)
close(fds[i]);

for (int i = 0; i < num_pipe + 1; i++)
{
int status;
pid_t pid = wait(&status);
printf("PID %d exited 0x%.4X\n", (int)pid, status);
}

return 0;
}

static void err_exit(const char *str)
{
perror(str);
exit(EXIT_FAILURE);
}

检查是否适合您。然后你需要弄清楚你将如何创建第二个命令。您的 arrayOfCommands 不会直接提供帮助。您将需要另一个具有某种形状或形式的字符串数组。


运行 cat 文件的扩展 |转。变化真的很小。我创建了 a_cat 来处理 cat 命令,为 rev 命令创建了 a_rev,以及 a_cmds 作为命令数组。还需要将 i 上的循环修复为 k 上的循环。

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

static void err_exit(const char *str);

int main (int argc, char **argv)
{
int num_pipe = 1;
int commands = num_pipe + 1; //number of commands is one more than the number of pipes
int fds[num_pipe * 2 + 1]; // Avoid size 0 array
char *a_cat[3] = { "cat", NULL, NULL};
char *a_rev[2] = { "rev", NULL};
char **a_cmds[] = { a_cat, a_rev };

if (argc != 2)
err_exit("Missing filename argument");
a_cat[1] = argv[1];

for (int i = 0; i < num_pipe; i++)
{
if (pipe(fds + i * 2) == -1)
err_exit("Error creating pipes");
}

int j = 0;
for (int i = 0; i < commands; ++i)
{
pid_t pid = fork();

if (pid == 0)
{
printf("%d: %s\n", (int)getpid(), a_cmds[i][0]);
fflush(stdout);
if (i < commands-1 && dup2(fds[j+1], 1) < 0)
err_exit("dup2 error");
if (j != 0 && dup2(fds[j-2], 0) < 0)
err_exit("dup2 error");
for (int k = 0; k < 2*num_pipe; k++)
close(fds[k]);

execvp(a_cmds[i][0], a_cmds[i]);
err_exit("Array error");
}
else if (pid < 0)
err_exit("Error");

j += 2;
}

for (int i = 0; i < 2 * num_pipe; i++)
close(fds[i]);

for (int i = 0; i < num_pipe + 1; i++)
{
int status;
pid_t pid = wait(&status);
printf("PID %d exited 0x%.4X\n", (int)pid, status);
}

return 0;
}

static void err_exit(const char *str)
{
perror(str);
exit(EXIT_FAILURE);
}

关于c - 学习管道和流程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17904646/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com