C 程序中的命名管道 (unix)
Named pipes in C program (unix)
我必须使用3个进程才能解决这个问题。
第一个进程从(通过键盘输入)获取输入并将其发送到第二个进程
第二个过程将文本中的所有人声替换为 12345(a 替换为 1,e 替换为 2,...)。我得到了一个运行良好的 sh 脚本(对其进行了测试),它使用 sed 来完成这项任务。我会把它放在这里。
第三个过程仅在屏幕上输出字母数字行。我还有一个脚本,它使用 grep 来完成这个任务并且也工作正常(测试过)。
这个进程应该通过一个命名管道(一个 FIFO 文件)进行通信,我 运行 在通过 FIFO 发送和接收数据时遇到了一些困难。当我使用写入功能将数据写入 FIFO 时,它会在屏幕上输出数据,而当我在第二个进程中并尝试从 FIFO 读取数据时,它只是等待我输入的新输入。
第一个过程:
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
int main() {
char text[500]; // buffer for the inputed text
char aux[100]; // Also a buffer to save multi-line input into text buffer
char* myfifo = "myfifo";
int fd_text;
printf("\nInput: (to stop giving input just type 0 on a new line):\n");
// Forming the text
while(scanf("%[^\n]%*c", aux) == 1) {
if(strcmp(aux, "0") == 0)
break;
strcat(aux, "\n");
strcat(text, aux);
}
strcat(text, "[=10=]");
// Everything works well reading the input
int returnValue = mkfifo(myfifo, 0666);
if(returnValue < 0) {
printf("mkfifo() failed\nerrno = %d\n", errno);
if(errno == EEXIST)
printf("That file already exists.\n");
}
if(fd_text = open(myfifo, O_WRONLY) < 0) {
printf("error while opening FIFO");
exit(0);
}
int indicator = write(fd_text, text, strlen(text) + 1);
if(indicator == 0) {
printf("error while writing to FIFO");
}
close(fd_text);
return 0;
}
第二个过程:
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
int main() {
char text[500];
char* myfifo = "myfifo";
int fd_text2;
if (fd_text2 = open(myfifo, O_RDONLY) < 0) {
printf("error while opening FIFO");
exit(1);
}
int result = read(fd_text2, text, 500);
if (result < 0)
printf("ERROR WHILE READING FROM THE FILE\n");
printf("\n%d bytes were read from the file\n", result);
printf("\nText read from FIFO:\n%s\n", text);
// Saving the text into a txt to perfom the sed command on it
FILE *fp_replace_text;
fp_replace_text = fopen("replace_text.txt", "w");
fprintf(fp_replace_text, "%s", text);
fclose(fp_replace_text);
system("chmod 777 replace.sh");
system("./replace.sh replace_text.txt");
close(fd_text2);
unlink(myfifo);
return 0;
}
replace.sh
#!/bin/sh
sed -i 's/a/1/gi'
sed -i 's/e/2/gi'
sed -i 's/i/3/gi'
sed -i 's/o/4/gi'
sed -i 's/u/5/gi'
如果我能弄清楚为什么进程 1 和进程 2 之间的通信不起作用,那么进程 3 将是相同的,所以我不再发布它了。
编辑:
第二个过程
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
int main() {
char text[500];
char* myfifo = "myfifo";
int fd_text2;
if ((fd_text2 = open(myfifo, O_RDWR)) < 0) {
printf("error while opening pipe");
exit(1);
}
int result = read(fd_text2, text, 500);
if (result < 0)
printf("ERROR WHILE READING FROM THE FILE\n");
FILE *fp_replace_text;
fp_replace_text = fopen("replace_text.txt", "w");
fprintf(fp_replace_text, "%s", text);
fclose(fp_replace_text);
system("chmod 777 replace.sh");
system("./replace.sh replace_text.txt");
fp_replace_text = fopen("replace_text.txt", "r");
fread(text, 500, 1, fp_replace_text);
fclose(fp_replace_text);
write(fd_text2, text, strlen(text) + 1);
close(fd_text2);
return 0;
}
第三道工序
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
int main() {
char text[500];
char* myfifo = "myfifo";
int fd_text3;
if ((fd_text3 = open(myfifo, O_RDONLY)) < 0) {
printf("error while opening pipe");
exit(1);
}
int result = read(fd_text3, text, 500);
if (result < 0)
printf("ERROR WHILE READING FROM THE FILE\n");
FILE *fp_replace_text;
fp_replace_text = fopen("replace_text.txt", "r");
fread(text, 500, 1, fp_replace_text);
fclose(fp_replace_text);
printf("Textul final este:\n");
system("chmod 777 output.sh");
system("./output.sh replace_text.txt");
unlink(myfifo);
return 0;
}
我也在尝试通过 FIFO 将 txt 文件的内容发送到第三个进程(我知道我可以只使用 txt 文件,但我想使用 FIFO 文件并再次从中读取)。所以我在 txt 文件上使用 shell 脚本,我从中读取然后我想将从 txt 文件读取的内容发送到第三个进程到 FIFO,但是在我 运行 之后第二个进程执行停止并且不阻塞。当我在第一个进程中写入 FIFO 时,它会阻塞,直到第二个进程从 FIFO 读取数据。第二个进程继续执行,第三个进程什么也得不到。我想 FIFO 原则一定有问题,如果你想在 FIFO 上执行 input/output 操作,两端都应该打开。
问题(应该引起编译器的警告)是在这样的语句中:
if(fd_text = open(myfifo, O_WRONLY) < 0)
您似乎假设这将从左到右进行评估,首先为 fd_text
赋值,然后根据 0 测试该值以给出一个布尔值,该值将决定是否输入 if
块。但在 C 中,关系 运算符(如 <
)优先于 赋值 运算符(如 =
)。所以首先我们将 open
命令的结果与 0 进行比较,然后将比较的布尔结果赋值给 fd_text
。因此文件描述符丢失,进一步尝试到达 fifo 将失败。我们可以用一对括号来纠正这个问题:
if((fd_text = open(myfifo, O_WRONLY)) < 0)
更一般地说,尽可能独立开发新功能是个好主意。如果你想将文本发送到 fifo 并接收它,只需在第一个模块中硬编码一些文本,不需要所有的代码来读取用户输入,并且不要尝试从 fifo 发送文本的进一步步骤第二个模块到其他一些修改过程,直到 fifo 工作正常。小步骤。
我必须使用3个进程才能解决这个问题。 第一个进程从(通过键盘输入)获取输入并将其发送到第二个进程 第二个过程将文本中的所有人声替换为 12345(a 替换为 1,e 替换为 2,...)。我得到了一个运行良好的 sh 脚本(对其进行了测试),它使用 sed 来完成这项任务。我会把它放在这里。 第三个过程仅在屏幕上输出字母数字行。我还有一个脚本,它使用 grep 来完成这个任务并且也工作正常(测试过)。 这个进程应该通过一个命名管道(一个 FIFO 文件)进行通信,我 运行 在通过 FIFO 发送和接收数据时遇到了一些困难。当我使用写入功能将数据写入 FIFO 时,它会在屏幕上输出数据,而当我在第二个进程中并尝试从 FIFO 读取数据时,它只是等待我输入的新输入。
第一个过程:
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
int main() {
char text[500]; // buffer for the inputed text
char aux[100]; // Also a buffer to save multi-line input into text buffer
char* myfifo = "myfifo";
int fd_text;
printf("\nInput: (to stop giving input just type 0 on a new line):\n");
// Forming the text
while(scanf("%[^\n]%*c", aux) == 1) {
if(strcmp(aux, "0") == 0)
break;
strcat(aux, "\n");
strcat(text, aux);
}
strcat(text, "[=10=]");
// Everything works well reading the input
int returnValue = mkfifo(myfifo, 0666);
if(returnValue < 0) {
printf("mkfifo() failed\nerrno = %d\n", errno);
if(errno == EEXIST)
printf("That file already exists.\n");
}
if(fd_text = open(myfifo, O_WRONLY) < 0) {
printf("error while opening FIFO");
exit(0);
}
int indicator = write(fd_text, text, strlen(text) + 1);
if(indicator == 0) {
printf("error while writing to FIFO");
}
close(fd_text);
return 0;
}
第二个过程:
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
int main() {
char text[500];
char* myfifo = "myfifo";
int fd_text2;
if (fd_text2 = open(myfifo, O_RDONLY) < 0) {
printf("error while opening FIFO");
exit(1);
}
int result = read(fd_text2, text, 500);
if (result < 0)
printf("ERROR WHILE READING FROM THE FILE\n");
printf("\n%d bytes were read from the file\n", result);
printf("\nText read from FIFO:\n%s\n", text);
// Saving the text into a txt to perfom the sed command on it
FILE *fp_replace_text;
fp_replace_text = fopen("replace_text.txt", "w");
fprintf(fp_replace_text, "%s", text);
fclose(fp_replace_text);
system("chmod 777 replace.sh");
system("./replace.sh replace_text.txt");
close(fd_text2);
unlink(myfifo);
return 0;
}
replace.sh
#!/bin/sh
sed -i 's/a/1/gi'
sed -i 's/e/2/gi'
sed -i 's/i/3/gi'
sed -i 's/o/4/gi'
sed -i 's/u/5/gi'
如果我能弄清楚为什么进程 1 和进程 2 之间的通信不起作用,那么进程 3 将是相同的,所以我不再发布它了。
编辑:
第二个过程
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
int main() {
char text[500];
char* myfifo = "myfifo";
int fd_text2;
if ((fd_text2 = open(myfifo, O_RDWR)) < 0) {
printf("error while opening pipe");
exit(1);
}
int result = read(fd_text2, text, 500);
if (result < 0)
printf("ERROR WHILE READING FROM THE FILE\n");
FILE *fp_replace_text;
fp_replace_text = fopen("replace_text.txt", "w");
fprintf(fp_replace_text, "%s", text);
fclose(fp_replace_text);
system("chmod 777 replace.sh");
system("./replace.sh replace_text.txt");
fp_replace_text = fopen("replace_text.txt", "r");
fread(text, 500, 1, fp_replace_text);
fclose(fp_replace_text);
write(fd_text2, text, strlen(text) + 1);
close(fd_text2);
return 0;
}
第三道工序
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
int main() {
char text[500];
char* myfifo = "myfifo";
int fd_text3;
if ((fd_text3 = open(myfifo, O_RDONLY)) < 0) {
printf("error while opening pipe");
exit(1);
}
int result = read(fd_text3, text, 500);
if (result < 0)
printf("ERROR WHILE READING FROM THE FILE\n");
FILE *fp_replace_text;
fp_replace_text = fopen("replace_text.txt", "r");
fread(text, 500, 1, fp_replace_text);
fclose(fp_replace_text);
printf("Textul final este:\n");
system("chmod 777 output.sh");
system("./output.sh replace_text.txt");
unlink(myfifo);
return 0;
}
我也在尝试通过 FIFO 将 txt 文件的内容发送到第三个进程(我知道我可以只使用 txt 文件,但我想使用 FIFO 文件并再次从中读取)。所以我在 txt 文件上使用 shell 脚本,我从中读取然后我想将从 txt 文件读取的内容发送到第三个进程到 FIFO,但是在我 运行 之后第二个进程执行停止并且不阻塞。当我在第一个进程中写入 FIFO 时,它会阻塞,直到第二个进程从 FIFO 读取数据。第二个进程继续执行,第三个进程什么也得不到。我想 FIFO 原则一定有问题,如果你想在 FIFO 上执行 input/output 操作,两端都应该打开。
问题(应该引起编译器的警告)是在这样的语句中:
if(fd_text = open(myfifo, O_WRONLY) < 0)
您似乎假设这将从左到右进行评估,首先为 fd_text
赋值,然后根据 0 测试该值以给出一个布尔值,该值将决定是否输入 if
块。但在 C 中,关系 运算符(如 <
)优先于 赋值 运算符(如 =
)。所以首先我们将 open
命令的结果与 0 进行比较,然后将比较的布尔结果赋值给 fd_text
。因此文件描述符丢失,进一步尝试到达 fifo 将失败。我们可以用一对括号来纠正这个问题:
if((fd_text = open(myfifo, O_WRONLY)) < 0)
更一般地说,尽可能独立开发新功能是个好主意。如果你想将文本发送到 fifo 并接收它,只需在第一个模块中硬编码一些文本,不需要所有的代码来读取用户输入,并且不要尝试从 fifo 发送文本的进一步步骤第二个模块到其他一些修改过程,直到 fifo 工作正常。小步骤。