我正在编写一个程序,将行号放在给定文本文档的每一行前面。我是通过使用管道来编写的,因为这样做的目的是了解管道的工作原理。
问题:当输入文件中有少量数据(大约150行)时,程序运行良好。当我输入更多行(200+)时,输出文件一直很好,直到第 153 行,然后它重复最后 40 行左右。
当我输入更多行(6000)时,程序永远不会结束,输出文件保持为空。
我不知道哪里出了问题,所以如果能得到一些帮助会很棒。
代码 :
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <wait.h>
#include <limits.h>
void Parent(int *ipPX, int *ipPY);
void Child(int *IpPX, int *IpPY);
FILE *ifp, *ofp; //input and output file
void fileHandling (char *argv[2]);
int main(int argc, char *argv[]) {
pid_t pid;
int pdX[2], pdY[2];
fileHandling(argv);
pipe(pdX);
pipe(pdY); //make new file descriptors in table
switch (pid = fork()) {
case 0: Child(pdX, pdY);
break;
case -1: perror("Error creating child");
exit(1);
default: Parent(pdX, pdY);
}
exit(EXIT_SUCCESS);
}
void Parent(int *ipPX, int *ipPY) {
char *line = NULL;
size_t len = 0;
ssize_t readedLines;
char buf[LINE_MAX];
int n;
close(ipPX[0]);close(ipPY[1]); //close not used fd's
while ((readedLines = getline(&line, &len, ifp)) > 0) {
write(ipPX[1], line, readedLines); //read from input file and write to cat process
}
close(ipPX[1]); //done with this fd
while ((n = read(ipPY[0], buf, sizeof (buf))) > 0) {
fprintf(ofp, "%s", buf); //read from cat process and print to file
}
close(ipPY[0]); //done with this fd
wait(0); //wait for child to finish
}
void Child(int *ipPX, int *ipPY) {
close(ipPX[1]);
close(ipPY[0]);
close(0);
dup(ipPX[0]);
close(ipPX[0]);
close(1);
dup(ipPY[1]);
close(ipPY[1]);
execlp("cat", "cat", "-n", NULL);
perror("Execlp error"); //not reached unless execlp fails
exit(1);
}
void fileHandling (char *argv[2]){
char *outputFile; //name of output file
if (!(ifp = fopen(argv[1], "r"))) {
fprintf(stderr, "Error opening input file");
exit(1);
}
if (argv[2] == NULL) {
outputFile = "LineNumbersOutput";
}
else {
outputFile = argv[2];
}
if (!(ofp = fopen(argv[2], "w+"))) {
fprintf(stderr, "Error opening output file");
exit(1);
}
}
更新:现在我添加了第三个进程,但是在之前的代码中添加的行号已经消失了。现在输出完成了(不管文件有多大)
感谢所有的大力帮助!
新代码:
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <wait.h>
#include <limits.h>
void Parent(int *ipPX, int *ipPY);
void CatProcess(int *IpPX, int *IpPY);
void WriteToFile(int *ipPX, int *ipPY);
FILE *ifp, *ofp; //input and output file
void FileHandling (char *argv[2]);
int main(int argc, char *argv[]) {
pid_t catpid;
pid_t writeToFile;
int pdX[2], pdY[2];
FileHandling(argv);
pipe(pdX);
pipe(pdY); //make new file descriptors in table
//first child
switch (catpid = fork()) {
case 0: CatProcess(pdX, pdY);
break;
case -1: perror("Error creating Cat child");
exit(1);
default:
writeToFile = fork();
}
//second child
switch (writeToFile){
case 0: WriteToFile(pdX, pdY);
break;
case -1: perror("Error creating writeToFile child");
exit(1);
default:
Parent(pdX, pdY);
}
exit(EXIT_SUCCESS);
}
void Parent(int *ipPX, int *ipPY) {
char *line = NULL;
size_t len = 0;
ssize_t readedLines;
close(ipPX[0]);close(ipPY[1]); close(ipPY[0]);//close not used fd's
while ((readedLines = getline(&line, &len, ifp)) > 0) {
write(ipPX[1], line, readedLines); //read from input file and write to cat process
}
close(ipPX[1]); //done with this fd
wait(0); //wait for child to finish
}
void CatProcess(int *ipPX, int *ipPY) {
close(ipPX[1]);
close(ipPY[0]);
close(0);
dup(ipPX[0]);
close(ipPX[0]);
close(1);
dup(ipPY[1]);
close(ipPY[1]);
execlp("cat", "cat", "-n", NULL);
perror("Execlp error"); //not reached unless execlp fails
exit(1);
}
void FileHandling (char *argv[2]){
char *outputFile; //name of output file
if (!(ifp = fopen(argv[1], "r"))) {
fprintf(stderr, "Error opening input file");
exit(1);
}
if (argv[2] == NULL) {
outputFile = "LineNumbersOutput";
}
else {
outputFile = argv[2];
}
if (!(ofp = fopen(argv[2], "w+"))) {
fprintf(stderr, "Error opening output file");
exit(1);
}
}
void WriteToFile(int *ipPY,int *ipPX){
char buf[LINE_MAX];
int n;
close(ipPY[1]); close(ipPX[0]); close(ipPX[1]); //close unused fd's
close(0); dup(ipPY[0]); close(ipPY[0]); //redirect stdin
while ((n = read(0, buf, sizeof (buf))) > 0) {
fprintf(ofp, "%s", buf); //read from cat process and print to file
}
}
画了一张图让自己看清楚(认为是正确的)