将比特流写入 C

问题描述

我目前正在尝试使用 CMP 解压缩器:https://web.archive.org/web/20070113004119/http://rewiki.regengedanken.de:80/wiki/.CMP

它实际上确实解压缩了 cmp,但它不会将其写入文件。 所以我自己试了一下。

int main(int argc,char** argv)
{
    int length,dstLength;
    unsigned char* fileInMem; //compressed data
    unsigned char* dstFile; //decompressed data

    if (argc < 2) {
        fprintf(stderr,"give filename.cmp as parameter\n");
        return 1;
    }

    printf("%s",argv[1]);

    fileInMem = loadFile(argv[1],&length); //compressed data read
    if (fileInMem == NULL) {
        return 1;
    }

    dstFile = parseCmp(fileInMem,length,&dstLength); //decompress and assign data to dstFile
    if (dstFile) {
        /* Now we can save the file from dstFile,dstLength bytes */
        printf("%d bytes depacked\n",dstLength);

        for (int i = 0; i < 16; i++) {
            dataArray[i] = fileInMem[i];
        }

            FILE *writer = fopen(argv[2],"r+");
            //fputs(fileInMem,writer);
            //fputs(dstFile,writer);
         
            fclose(writer);
        free(dstFile);
    }

    free(fileInMem);

    return 0;
}

如您所见,解压后的数据是一个指向无符号字符的指针(根据网站的比特流),我尝试了 stdio.h 中的 fputs(),但结果文件在以十六进制查看时仅包含 4 个字节 -编辑器。

如果您需要更多信息,请发表评论

提前致谢。

编辑:多亏了你的帮助,我才能够改变,但是当我打开文件时,它仍然是空的:

FILE* writer = fopen(argv[2],"wb");
fwrite(dstFile,192,writer);

192,因为第一个解压后的 Image 的长度是 192 Bytes 大。

解决方法

这是一个常见问题。

首先,您需要打开输出文件 writer 以二进制模式写入 ("wb")。

FILE *writer = fopen(argv[2],"wb");

其次,您不能使用 fputs 将任意数据写入文件,因为它需要一个字符串。使用 fwrite 代替:(假设 writer 是输出文件,dstFile 是解压缩数据,dstLength 是要写入的字节数)

fwrite(dstFile,1,dstLength,writer);

如果您使用十六进制编辑器检查生成的文件,您会发现它与解压后的数据完全相同。

测试更新

我编写了一些测试代码来查看问题所在,请分享您的结果以便我们为您提供帮助。

将这些函数添加到您的代码中:

void printDataToScreen(unsigned char *dataptr,int datalen)
{
    if (dataptr == NULL)
    {
        printf("[!] ERROR,NULL POINTER PROVIDED!\n");
        return;
    }
    printf("> Dumping %d bytes of data into the terminal...\n",datalen);
    for (int i = 0; i < datalen; i++)
    {
        if (i % 16 == 0)
            printf("\n   ");
        printf("%02X ",dataptr[i]);
    }
    printf("\n\n");
}

void writeDataToFile(char *fileName,unsigned char *dataptr,int datalen)
{
    FILE *file = fopen(fileName,"wb");
    if (dataptr == NULL)
    {
        printf("[!] ERROR,NULL POINTER PROVIDED!\n");
        return;
    } else if (file == NULL)
    {
        printf("[!] ERROR WHILE OPENING FILE '%s'!\n",fileName);
        return;
    }
    
    printf("> Writting %d bytes of data to '%s'...\n",datalen,fileName);
    int writtenBytes = fwrite(dataptr,file);
    printf("   Done,%d bytes written!\n\n",writtenBytes);
    
    fclose(file);
}

void runTest(char *fileName,int datalen)
{
    printf("Running tests... [0/2 done]\n");
    printDataToScreen(dataptr,datalen);
    printf("Running tests... [1/2 done]\n");
    writeDataToFile(fileName,dataptr,datalen);
    printf("Finished! [2/2 done]\n");
}

这样称呼它:

runTest(argv[2],dstFile,dstLength);

在您的代码中添加对此位置的调用(注释此代码,以及关闭 writer 的行):

FILE *writer = fopen(argv[2],"r+");
//fputs(fileInMem,writer);
//fputs(dstFile,writer);

请分享您的结果。