我可以在二进制文件中使用fgetc()或fputc()吗?

时间:2013-05-10 09:23:28

标签: c fwrite fread fgetc

我正在用C创建一个存档程序,我想要它保存我提供的文件,列出并提取它们。
我有很多问题,因为我使用文本文件进行保存,如果我想处理音乐或照片等二进制文件,它不是最佳选择,因为当我提取它们时,它们没有正确执行(它们已损坏)。 为了解决这个问题,我想创建一个二进制存档文件。

文件写入代码(提取时)如下:

void scriviFile(const char * arrivo)                                //scrive i file creati in precedenza
{
    FILE * partenza;
    FILE * target;
    int c;
    int spazio = 'a';
    int i = 0;
    int pos;
    char * path;
    path = collegaSlash(getcwd(NULL, 0), nome);
    partenza = fopen(path, "rb");
    fseek(partenza, inizio, SEEK_SET);
    target = fopen(arrivo, "wb");                                           //apro il file
    if (target) {                                                               //se è aperto
        while ((c = fgetc(partenza)) != EOF && ftell(partenza)<=fine-10) {                                  //e il carattere preso non eccede la fine del file
            fputc(c, target);
            fputc(c, stdout);
            pos = ftell(partenza);
            if(pos==fine)
            {
                break;
            }
                                                                            //scrivo lo stesso carattere in out (file in uscita)
        }                                                                   //

        fclose(target);                                                     //chiudo il file
        fclose(partenza);
    } 
    else 
    {
        printf("errore di scrittura del file \n");
    }

}

由于我需要正确提取二进制文件,我可以使用上面编写的代码,还是必须使用fgetc()和{{1更改所有fputc()fread()函数}}?

由于

2 个答案:

答案 0 :(得分:8)

您正在使用fgetc()fputc(),因为您可以从手册页说明中看到这些功能:

  

fgetc()从流中读取下一个字符,并将其作为无符号字符串转换为int,或者在文件末尾或错误时返回EOF。

     

fputc()将字符c(强制转换为无符号字符串)写入流。

C中的字符由标准定义为始终正好是1字节(8位),这意味着当您在文件上使用fxxxc()时,您将获得1个字节(恰好是文本文件中的字符)。

如果逐字节提取并重建二进制文件,则会得到完全相同的内容。所以不,在二进制文件类型上使用fgetc()fputc()没有问题。您总是可以通过一个简单的示例程序向自己证明这一点......例如:

int main()
{
    FILE * fptr = fopen("small_pic.jpg", "rb");  // open existing binary picture
    char buffer[10000] = {0}; // the pic is 6kb or so, so 10k bytes will hold it
    FILE * fptr2 = fopen("new_small_pic.jpg", "wb"); // open a new binary file 
                                                       // for our copy of the pic
    unsigned long fileLen;
    unsigned long counter;

    fseek(fptr, 0, SEEK_END);
    fileLen=ftell(fptr);      // get the exact size of the pic
    fseek(fptr, 0, SEEK_SET);

    for(counter=0; counter<fileLen; counter++)
        fputc(fgetc(fptr),fptr2);  // read each byte of the small_pic.jpg and make
                                           // a new pic from it

    fclose(fptr);
    fclose(fptr2);
return 0;
}

最终结果:我们有两个完全相同的图像,因为fgetc()fputc()可用于二进制文件。

答案 1 :(得分:0)

  

我正在用C创建一个归档程序,我希望它能保存文件i   提供,列出和提取它们。我有很多问题,因为我使用过   用于保存的文本文件,如果我愿意,它不是最佳选择   处理二进制文件,如音乐或照片,因为当我提取   它们,它们没有正确执行(它们已损坏)。为了   要解决这个问题,我想创建一个二进制存档文件。

     

- SNIP -

     

由于我需要正确提取二进制文件,我可以使用代码i   如上所述,或者我必须更改所有fgetc()和fputc()函数   用fread()和fwrite()?

在二进制模式下工作时,您可以使用上面编写的代码。它与fgetcfputcfreadfwrite无关。在文本模式下工作时此函数无法正常工作的原因是ftell不能保证对fseek以外的任何其他内容有用,因此代码{{1}在文本模式下打开文件时,不是特别合适。通过重构代码,您可以删除ftell(partenza)<=fine-10并使用大于4GB的文件...但这不应该是重构此代码的唯一原因。