【问题标题】:In C language binary file ioC语言中的二进制文件io
【发布时间】:2018-04-28 21:07:26
【问题描述】:

如果我将二进制文件输入到数组 buf,为什么我必须通过 (void*) 输入它? 为什么我必须用 (void*) 来写它??请遵守此代码,并向我解释此代码。 (我只是从我的书中复制了这段代码)

int main(void) {
FILE * src = fopen("a.png", "rb");
FILE * des = fopen("b.png", "wb");

char buf[20];
int readCnt;

if (src == NULL || des == NULL) {
    puts("File open failed");
    return -1;
}

while (1) {
    readCnt = fread((void*)buf, 1, sizeof(buf), src);

    if (readCnt < sizeof(buf)) {
        if (feof(src) != 0) {
            fwrite((void*)buf, 1, readCnt, des);
            puts("File copy complete");
            break;
        }
        else
            puts("File copy Failed");

        break;
    }
    fwrite((void*)buf, 1, sizeof(buf), des);
}
fclose(src);
fclose(des);
return 0;

}

【问题讨论】:

  • 这本书很旧吗?无需转换为void *c 中的每个指针都可以从void * 转换并返回而无需转换
  • uint64_t buf[20] 需要读取更多的 void*,但你可以用任何东西做文件 io

标签: c file io binary


【解决方案1】:

因为fread() & fwrite()通用函数,用于将二进制数据读写到文件irrespectivedata type 中。

fwrite() 的手册页说,

size_t fwrite(const void *ptr, size_t size, size_t nmemb,
                     FILE *stream);

第一个参数是什么,它的const void *ptr 表示它的期望地址。它可以是任何变量地址 int 或 char 或任何其他数据类型。

【讨论】:

    【解决方案2】:

    这样您就可以传递任何指针类型。所以举个例子,如果你想写一个像例子这样的结构

    struct point {
        int x;
        int y;
    };
    
    struct point my_point = {1, 2};
    FILE *file = fopen("sample-file.bin", "w");
    if (file != NULL) {
        // Normally check that this returns the number of
        // written items
        fwrite(&my_point, 1, sizeof(my_point), file);
        fclose(file);
    }
    

    可以,当您打开文件进行阅读时,您也可以fread(&amp;my_point ...)

    请注意, 中不需要转换为 void *,例如,也不需要从 void * 转换为另一种指针类型

    char *example = malloc(size + 1);
    

    完全有效,malloc() 返回void *

    【讨论】:

      【解决方案3】:

      转换为void* 是因为这是函数所期望的。请参阅herehere

      您的代码将在没有此强制转换的情况下编译,因为没有必要强制转换为 void*(请参阅下面的引用),但我想作者希望尽可能准确。

      6.3.2.3 指针

      1 指向 void 的指针可以转换为指向任何不完整或对象类型的指针或从指针转换。指向任何不完整或对象类型的指针可以转换为指向 void 的指针并再次返回;结果应与原始指针比较。

      另一件事 - (void*) 是抑制编译器警告的好方法。开始可能不是一件好事(警告是有原因的),但如果需要,这是一种忽略函数参数中错误指针类型的简单方法。

      【讨论】:

      • 恕我直言,有多余的指针转换是不好的风格。与void * 之间的转换是隐含的,有充分的理由......
      • @FelixPalmen 我不知道。我经常看到。一个函数需要int*,但提供的是unsigned int*。我多次看到的修复是(void*)。关于不良风格 - 完全同意。我不会写这样的代码
      • 指针转换的唯一“好”原因是糟糕的设计。
      • 确实如此。但遗憾的是,并非我们所有人都从上到下编写代码。看到这样的问题源于糟糕的设计 - 这是一个简单的修复
      • @JensGustedt 或打印一个指针(更一般地说,将通用指针传递给可变参数函数)。或使用 char * 别名来检查表示。但我同意你应该避免指针转换,因为你需要它们的任何地方都是代码中需要特别注意不要违反严格别名等的地方——这是我反对 casting the malloc() result 的主要论点。
      【解决方案4】:

      这可能应该是一个评论,但我没有这方面的声誉。在您的代码中:

      if (src == NULL || des == NULL) { puts("File open failed"); return -1; }

      有可能 src 或 des 可能已正确打开,因此应该调用 fclose();

      类似:

      if (src == NULL || des == NULL) 
      {
            if(src)
            {
              fclose(src);
            }
            if(des)
            {
              fclose(des);
            }
            puts("File open failed");
            return -1;
        }
      

      会更好。

      【讨论】:

        猜你喜欢
        • 2012-01-11
        • 2021-08-17
        • 2018-11-30
        • 2010-12-14
        • 2020-12-19
        • 2017-03-04
        • 2021-11-27
        • 2014-03-01
        • 1970-01-01
        相关资源
        最近更新 更多