【发布时间】:2023-03-14 06:18:01
【问题描述】:
我有一个内容为abcefghz 的输入文件。我想使用管道,以便子进程 p1 每次向其父进程发送 1 个字母,父进程将使用 ASCII 码+1 转换此字符串(abcefghz 将变为cdfghi{)。这个新字符串将通过另一个管道发送到另一个子进程,该子进程将在输出文件上打印结果。
这是代码:
int main (int argc, char **argv)
{
pid_t pid1, pid2;
int inputFile, outputFile;
char stringaDalFile[256];
char successivo;
char stringaRisultato[256];
int fd1[2], fd2[2]; // Pipe
inputFile = open(argv[1], O_RDONLY);
outputFile = open(argv[2], O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
pipe(fd1);
pipe(fd2);
pid1 = fork();
if (pid1 == 0) {
while ( (nread=read(inputFile, stringaDalFile, 1)) > 0) {
close(fd1[0]);
write(fd1[1], stringaDalFile, 1);
}
close(inputFile);
}
else {
close(fd1[1]);
while ( read(fd1[0], stringaDalFile, 1) > 0 ) {
successivo = converti(stringaDalFile[0]);
write(fd2[1], &successivo, 1);
}
}
pid2 = fork();
if (pid2 == 0) {
close(fd2[1]);
if (read(fd2[0], stringaRisultato, 1) == -1) {
perror("Errore");
exit(1);
}
else {
while ( read(fd2[0], stringaRisultato, 1) > 0 ) {
write(STDOUT_FILENO, stringaRisultato, strlen(stringaRisultato)); //dbg
write(outputFile, stringaRisultato, strlen(stringaRisultato));
}
}
close(outputFile);
exit(0);
}
return 0;
}
char converti (char carattere)
{
return carattere+1;
}
不幸的是,这似乎不能 100% 工作,字符串被转换但程序进入了一个似乎是无限循环的状态:
如果我CTRL-C 和gedit file2.txt,这是它的内容:
.
我该如何解决这个问题?
【问题讨论】:
-
您永远不会将
stringaDalFile初始化为任何值,因此它永远不是正确的'\0'终止字符串。 -
我该如何解决?
-
您似乎只使用了
stringaDalFile[0],因此它不必以 NUL 结尾。但它也不必是大小为 256 的数组,1 应该就足够了。 -
但是令人担忧的问题是:奇怪的是,您甚至在凝视 p2 之前就将转换后的数据写入管道。对于大量不起作用的数据。而且您不会关闭父级管道的写入端,因此 p2 永远不会获得 EOF 而是无限等待更多数据
-
顺便说一句:你使用
strlen(stringaRisultato)。如果您没有终止缓冲区,那 是 错误的。但就像在其他循环中一样,如果您一次只读取一个字节,则可以将strlen()替换为 1。
标签: c file io pipe system-calls