读取报告 Bad File Descriptor 尽管 getc 成功使用相同的 fd 读取 char

Read reports Bad File Descriptor despite getc successfully using the same fd to read a char

我有这个 C 代码:

FILE * fd = fopen(filename,"rb");
printf("%c ",(char)getc(fd)); // returns expected char
unsigned char buffer[10];
printf("%d ",read(fd, &buffer, 10)); // -1
printf("%d\n",errno); // 9

getc returns 来自输入文件的一个字符,正如预期的那样。但是 read returns 错误 (-1) 并且 errno 设置为 9(错误的文件描述符)。显然文件描述符是正确的,因为 getc 设法使用它来读取一个字符。

这里有什么问题?

fopenread是不同族的函数。这些家庭是:

  • fopenfread(以及 getc),来自 C 标准库。

  • openread,来自 POSIX 规范。

第一个家族使用文件指针作为 FILE* 类型,而第二个家族使用文件描述符作为 int 类型。只要不从一种文件描述符类型转换为另一种文件描述符类型,就不能混合使用这两个系列。从 FILE*int 的转换是通过 POSIX 函数 fileno.

完成的

对于您的情况,请使用 fread 从文件中读取。

这是奇怪的代码。你想打印读取的 return 代码,而不是读取的数据?

首先修复你的阅读,你需要 fread 而不是阅读:

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *" stream );

崩溃是因为你覆盖了buffer的地址,你没有写入buffer本身

因此 printf("%d ",read(fd, &buffer, 10)); 应该是 printf("%d ",fread(buffer, 1, 10, fd));,以便将 10 (nmemb=10) 个字节 (size=1) 读入缓冲区。

而不是read(fd, &buffer, 10)
您要使用:fread(buffer, 1, 10, fd)

a FILE* 不是文件描述符,它是一个流;这就是为什么您必须使用 fread() (需要流)而不是 read() (需要文件描述符)的原因。此外,应该使用 buffer 而不是 &buffer(这会导致 UB)。