[英]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.