简单复制文件c程序在使用fgets()和fputs()组合时返回损坏的文件.它可以与getc()和putc()一起工作.



下面的程序获取附属于stdin的文件并将其复制到附属于stdout的文件中。如果我使用fgets()fputs()复制的文件损坏,但当我使用getc()putc()时,一切都很好。为什么呢?

下面是我在终端上输入的命令代码:
int main(int arg, char *argv[]) {
int c;
char buff[1024];
char *p;

while ((p = fgets(buff, sizeof(buff), stdin)) != NULL) {
fputs(buff, stdout);
}
return 0;
}

命令类型:

./buff < cat.jpeg > cp_cat.jpeg

之后文件cp_cat.jpeg被损坏。

复制的JPEG文件损坏有两个原因:

  • 文件在遗留系统上以文本模式打开,其中行结束序列从输入流(删除CR/LF对中的CR或可能所有CR字节)和输出流(将'n'转换为CR LF对)中进行翻译。在这样的系统上,stdinstdout默认处于文本模式,您必须使用非标准api(如_set_fmode(_O_BINARY))来更改这一点。然而,当使用getc()putc()时,这也会破坏JPEG文件,所以你可能使用macOS或其他unix系统。

  • fgets()/fputs()不能用于复制包含空字节的文件,因为fgets()存储到缓冲区中的空字节被fputs()解释为字符串的结尾,导致缓冲区的其余部分被忽略。这个问题没有解决的办法。为了缓冲复制过程,您可以使用fread()fwrite()来读取和写入字节块,并且必须确保流以二进制模式运行。

下面是一个例子:

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char buff[1024];
size_t nread;

#ifdef _MSC_VER 
_set_fmode(_O_BINARY);  // default to binary I/O
#endif
while ((nread = fread(buff, 1, sizeof buff, stdin)) != 0) {
if (fwrite(buff, 1, nread, stdout) != nread) {
fprintf(stderr, "error writing to stdout: %sn", strerror(errno));
return 1;
}
}
return 0;
}

相关内容

  • 没有找到相关文章

最新更新