无法通过 C 中的 fwrite 和 fread 复制文本文件

标签 c file file-io fwrite fread

这是代码:

#include <stdio.h>
#include <stdlib.h>

int main() {
    FILE *f, *fp;
    char buff[512];
    int buff_size;
    int bytes;

    fp = fopen("File.txt", "rb");

    if (fp == NULL) {
        printf("Cannot Open Source File!\n");
        exit(1);
    }

    f = fopen("append.txt", "ab+");

    if (f == NULL) {
        printf("Cannot Open Target File!\n");
        fclose(fp);
        exit(1);
    }

    buff_size = sizeof(buff);

    while (bytes = fread(&buff, buff_size, 1, fp) > 0) {
        if (bytes > 0)
            fwrite(&buff, buff_size, 1, f);
        else
            break;

        printf("Appending...\n\n");
    }

    rewind(f);

    while (bytes = fread(&buff, buff_size, 1, f) > 0)
        if (bytes > 0)
            printf("%s", buff);


    fclose(fp);
    fclose(f);
}

所以,它恰好没有输出任何内容,当我检查文件“append.txt”时,它也不包含任何内容。 请注意,源文件“File.txt”不为空。 谁能告诉我这是怎么回事?

编辑:

我通过替换 buff_size 解决了这个问题与 strlen(buff)像这样: bytes = fread(&buff, strlen(buff), 1, f) > 0fwrite() 相同第二个fread() .

有人能解释一下为什么会这样吗?

最佳答案

char buff[512];
int buff_size;

// [...]

bytes = fread(&buff, buff_size, 1, fp)

这将尝试读取 512 字节的一个 block 。返回值是读取的 block 数,因此不会是字节。但抛开这一点,如果您的文件小于 512 字节,则不会读取任何内容。

您想要的是读取 512 次 1 个字节,然后您将得到字节计数,因此将位置交换为 buff_size1 .

<小时/>

旁注:

  • 如果您在循环条件中正确执行检查,例如:

    while ((bytes = fread(buff, 1, buff_size, fp)) > 0 )
    

    额外检查if (bytes > 0)是多余的。

  • 写入时,您只想写入实际读取的字节数:

    fwrite(buff, 1, bytes, f);
    
  • 对于尺寸,请始终使用 size_t -- int很可能是错误的:

    size_t buff_size;
    size_t bytes;
    
  • 打印您的buffprintf("%s", )未定义的行为,因为您没有添加 '\0' fread() 读取数据后的字节。 C 字符串必须以 '\0' 结尾。当fread()读取数据时不包含'\0'偶然,printf()将读取和使用未初始化的数据,甚至可能读取超出 buff 范围的数据.

关于无法通过 C 中的 fwrite 和 fread 复制文本文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44740888/

相关文章:

c - 如何替换txt文件中的一行?

java - 在 android 中从 byte[] 写入文件失败

javascript - 使用 AJAX 在 IE 8 中处理 http_request

c - 检索数组的元素

c - 写入文件

java - 获取指定文件路径的file.separator

c - 使用 C 将 CFG 从文件读取到链表中

c - C 中的结构和二维数组错误

c - 互联网校验和中的位移位

来自 wireshark 的客户端 Hello TCP 重传