[英]Named pipes in C program (unix)
我必须使用 3 个进程才能解决问题。 第一个进程从(通过键盘输入)获取输入并将其发送到第二个进程。第二个进程将文本中的所有声音替换为 12345(a 与 1,e 与 2,...)。 我得到了一个运行良好的 sh 脚本(经过测试),它使用 sed 来完成这项任务。 我会把它放在这里。 第三进程仅在屏幕上输出字母数字行。 我还有一个脚本,它使用 grep 来完成这项任务,并且工作正常(经过测试)。 这个过程应该通过一个名为 pipe(一个 FIFO 文件)进行通信,并且我在通过 FIFO 发送和接收数据时遇到了一些困难。 当我使用写入 function 将数据写入 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, "\0");
// 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;
}
替换.sh
#!/bin/sh
sed -i 's/a/1/gi' $1
sed -i 's/e/2/gi' $1
sed -i 's/i/3/gi' $1
sed -i 's/o/4/gi' $1
sed -i 's/u/5/gi' $1
如果我能弄清楚为什么进程 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 filo 的内容发送到第三个进程(我知道我可以只使用 txt 文件,但我想使用 FIFO 文件并再次从中读取)。 所以我在 txt 文件上使用 shell 脚本,我从 txt 文件中读取,然后我想将我从 txt 文件中读取的内容发送到第三个进程到 FIFO,但是在我运行第二个进程之后,执行停止并且没有t 块。 当我在第一个进程中写入 FIFO 时,它会阻塞,直到第二个进程从 FIFO 中读取。 第二个进程继续执行,第三个进程什么也得不到。 我想 FIFO 原则一定有问题,如果你想在 FIFO 上执行输入/输出操作,应该打开两端。
问题(应该会导致编译器发出警告)出现在如下语句中:
if(fd_text = open(myfifo, O_WRONLY) < 0)
您似乎假设这将从左到右进行评估,首先为fd_text
分配一个值,然后针对 0 测试该值以给出 boolean 值,该值将确定是否进入if
块。 但是在 C 中,关系运算符(如<
)优先于赋值运算符(如=
)。 因此,首先我们将open
命令的结果与 0 进行比较,然后将该比较的 boolean 结果分配给fd_text
。 因此文件描述符丢失了,进一步尝试到达 fifo 将失败。 我们可以用一对括号来纠正这个问题:
if((fd_text = open(myfifo, O_WRONLY)) < 0)
更一般地说,尽可能孤立地开发新功能是个好主意。 如果您想将文本发送到 fifo 并接收它,只需在第一个模块中硬编码一些文本,没有所有代码来读取用户输入,并且不要尝试从第二个模块到其他一些过程进行修改,直到先进先出完美工作。 小步骤。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.