读取整个管道 - c
Read an entire pipe - c
我在使用这段代码时遇到了一些困难。
我需要从管道末端获取所有信息。
但是,我收到段错误。
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
int main(void){
int tube[2];
if(pipe(tube) == -1){
perror("Erreur");
exit(1);
}
dup2(tube[1],1);
printf("Few lines \n");
printf("of an undefined size. \n");
while (!feof(tube[0])) {
char temp = fgetc(tube[0]);
printf("chaine : %c\n", temp);
}
return 0;
}
如果您知道我如何处理这个问题,请解释一下。
您使用的函数 returns 单个字符 (fgetc) 然后将该值视为指向 printf 调用中的字符串的指针。您还将该字符存储为指向字符的指针的地址而不是实际字符,因此当 printf 读取您的字符串时,它正在读取一些它不拥有的低内存。 fgetc returns 字符本身,你需要一个 char 变量,而不是 char*.
尝试:
while (!feof(tube[0])) {
char temp = fgetc(tube[0]);
printf("chaine : %c\n", temp);
}
pipe
函数 returns 是一对 int
文件描述符,而不是 FILE
对。这意味着您可以对它们使用 read
、write
或 close
,但不能使用 fgetc
或 feof
.
此外,while(!feof(file))
(几乎)总是 wrong,因为在 不成功的读取到达文件末尾后 设置了标志.
这还不是全部。当写入端的所有描述符都关闭时,您只会在管道的读取端获得 EOF。所以你必须关闭或刷新 stdout
以确保所有字符都已写入管道,如果你没有关闭 stdout 则关闭文件描述符 1,并关闭 tube[1]
这仍然是文件描述符的写完管子。
因此您可以将 while 循环替换为:
close(tube[1]);
fclose(stdout);
while (1) {
char temp;
if (read(tube[0], &temp, 1) < 1) break;
fprintf(stderr, "chaine : %c\n", temp);
}
它修复了由于在非 FILE
上使用 feof
和 fgetc
导致的 SEGFAULT,并确保在读取文件之前正确关闭文件的写入端content 以获得良好的文件结束条件。
但是,我收到段错误。 ? 这意味着您没有正确阅读编译器警告。当你做 feof(tube[0])
它说 feof()
期望 FILE*
但你提供了 int
(tube[0]
is inetger) type.
/usr/include/stdio.h:828:12: note: expected ‘struct FILE *’ but
argument is of type ‘int’
所以第一件事总是阅读编译器警告并使用 -Wall
标志编译代码。
这个fgetc(tube[0]);
不是从file descriptor
读取数据的方式,使用read()
系统调用从文件描述符读取数据不是fgetc()
。 fgetc()
如果您使用 fopen()
打开文件,则可以使用。
还有
dup2(tube[1],1); /* this is not expected one which you want*/
这样使用
dup2(1,tube[1]);/*stdout get duplicated with tube[1] i.e whatever you
write on stdout will be written into write end of pipe*/
这是一个简单的例子。
char temp[100];
int ret = 0;
ret = read(tube[0],temp,sizeof(temp));/*reading from pipe*/
if(ret == -1) {
perror("read");
return 0;
}
else {
temp[ret] = '[=12=]';/*read returns no of items read, so put null
at last otherwise you may get some junk data */
printf("%s",temp);
}
阅读 man 2 read
& man 2 dup2
了解这些系统调用的工作原理..
我在使用这段代码时遇到了一些困难。 我需要从管道末端获取所有信息。 但是,我收到段错误。
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
int main(void){
int tube[2];
if(pipe(tube) == -1){
perror("Erreur");
exit(1);
}
dup2(tube[1],1);
printf("Few lines \n");
printf("of an undefined size. \n");
while (!feof(tube[0])) {
char temp = fgetc(tube[0]);
printf("chaine : %c\n", temp);
}
return 0;
}
如果您知道我如何处理这个问题,请解释一下。
您使用的函数 returns 单个字符 (fgetc) 然后将该值视为指向 printf 调用中的字符串的指针。您还将该字符存储为指向字符的指针的地址而不是实际字符,因此当 printf 读取您的字符串时,它正在读取一些它不拥有的低内存。 fgetc returns 字符本身,你需要一个 char 变量,而不是 char*.
尝试:
while (!feof(tube[0])) {
char temp = fgetc(tube[0]);
printf("chaine : %c\n", temp);
}
pipe
函数 returns 是一对 int
文件描述符,而不是 FILE
对。这意味着您可以对它们使用 read
、write
或 close
,但不能使用 fgetc
或 feof
.
此外,while(!feof(file))
(几乎)总是 wrong,因为在 不成功的读取到达文件末尾后 设置了标志.
这还不是全部。当写入端的所有描述符都关闭时,您只会在管道的读取端获得 EOF。所以你必须关闭或刷新 stdout
以确保所有字符都已写入管道,如果你没有关闭 stdout 则关闭文件描述符 1,并关闭 tube[1]
这仍然是文件描述符的写完管子。
因此您可以将 while 循环替换为:
close(tube[1]);
fclose(stdout);
while (1) {
char temp;
if (read(tube[0], &temp, 1) < 1) break;
fprintf(stderr, "chaine : %c\n", temp);
}
它修复了由于在非 FILE
上使用 feof
和 fgetc
导致的 SEGFAULT,并确保在读取文件之前正确关闭文件的写入端content 以获得良好的文件结束条件。
但是,我收到段错误。 ? 这意味着您没有正确阅读编译器警告。当你做 feof(tube[0])
它说 feof()
期望 FILE*
但你提供了 int
(tube[0]
is inetger) type.
/usr/include/stdio.h:828:12: note: expected ‘struct FILE *’ but argument is of type ‘int’
所以第一件事总是阅读编译器警告并使用 -Wall
标志编译代码。
这个fgetc(tube[0]);
不是从file descriptor
读取数据的方式,使用read()
系统调用从文件描述符读取数据不是fgetc()
。 fgetc()
如果您使用 fopen()
打开文件,则可以使用。
还有
dup2(tube[1],1); /* this is not expected one which you want*/
这样使用
dup2(1,tube[1]);/*stdout get duplicated with tube[1] i.e whatever you
write on stdout will be written into write end of pipe*/
这是一个简单的例子。
char temp[100];
int ret = 0;
ret = read(tube[0],temp,sizeof(temp));/*reading from pipe*/
if(ret == -1) {
perror("read");
return 0;
}
else {
temp[ret] = '[=12=]';/*read returns no of items read, so put null
at last otherwise you may get some junk data */
printf("%s",temp);
}
阅读 man 2 read
& man 2 dup2
了解这些系统调用的工作原理..