2016-09-15 30 views
0

を動作していないファイルに、私は単純に次の手順を実行するために、私が働いているこの手順を持っている:C++のZlib fwriteの

  1. オープンgzipで圧縮されたファイル
  2. それ解凍するのstdに::文字列
  3. STDからそれを圧縮する::文字列
  4. 保存gzip圧縮されたファイル

しかし、私は最後にgzip圧縮されたデータを書き込むように見えることはできません。私が得ているエラーは次のとおりです。「fwrite」への一致する関数呼び出しがありません。

間違ったパラメータを入力していますか?または間違ったタイプですか?ここで

は完全な手順です:

#include <iostream> 
#include "zlib-1.2.8/zlib.h" 
#include <stdexcept> 
#include <iomanip> 
#include <sstream> 
#include <stdio.h> 
#include <assert.h> 
#include <cstdio> 
#include <string> 
#include <cstring> 
#include <cstdlib> 
#include "zlib.h" 
#include "zconf.h" 

#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__) 
# include <fcntl.h> 
# include <io.h> 
# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) 
#else 
# define SET_BINARY_MODE(file) 
#endif 

#define CHUNK 16384 

using namespace std; 

bool gzipInflate(const std::string& compressedBytes, std::string& uncompressedBytes) { 
    if (compressedBytes.size() == 0) { 
     uncompressedBytes = compressedBytes ; 
     return true ; 
    } 

    uncompressedBytes.clear() ; 

    unsigned full_length = compressedBytes.size() ; 
    unsigned half_length = compressedBytes.size()/2; 

    unsigned uncompLength = full_length ; 
    char* uncomp = (char*) calloc(sizeof(char), uncompLength); 

    z_stream strm; 
    strm.next_in = (Bytef *) compressedBytes.c_str(); 
    strm.avail_in = compressedBytes.size() ; 
    strm.total_out = 0; 
    strm.zalloc = Z_NULL; 
    strm.zfree = Z_NULL; 

    bool done = false ; 

    if (inflateInit2(&strm, (16+MAX_WBITS)) != Z_OK) { 
     free(uncomp); 
     return false; 
    } 

    while (!done) { 
     // If our output buffer is too small 
     if (strm.total_out >= uncompLength) { 
      // Increase size of output buffer 
      char* uncomp2 = (char*) calloc(sizeof(char), uncompLength + half_length); 
      memcpy(uncomp2, uncomp, uncompLength); 
      uncompLength += half_length ; 
      free(uncomp); 
      uncomp = uncomp2 ; 
     } 

     strm.next_out = (Bytef *) (uncomp + strm.total_out); 
     strm.avail_out = uncompLength - strm.total_out; 

     // Inflate another chunk. 
     int err = inflate (&strm, Z_SYNC_FLUSH); 
     if (err == Z_STREAM_END) done = true; 
     else if (err != Z_OK) { 
      break; 
     } 
    } 

    if (inflateEnd (&strm) != Z_OK) { 
     free(uncomp); 
     return false; 
    } 

    for (size_t i=0; i<strm.total_out; ++i) { 
     uncompressedBytes += uncomp[ i ]; 
    } 
    free(uncomp); 
    return true ; 
} 



/** Compress a STL string using zlib with given compression level and return 
* the binary data. */ 
std::string compress_string(const std::string& str, int compressionlevel = Z_BEST_COMPRESSION) 
{ 
    z_stream zs;      // z_stream is zlib's control structure 
    memset(&zs, 0, sizeof(zs)); 

    if (deflateInit(&zs, compressionlevel) != Z_OK) 
     throw(std::runtime_error("deflateInit failed while compressing.")); 

    zs.next_in = (Bytef*)str.data(); 
    zs.avail_in = str.size();   // set the z_stream's input 

    int ret; 
    char outbuffer[32768]; 
    std::string outstring; 

    // retrieve the compressed bytes blockwise 
    do { 
     zs.next_out = reinterpret_cast<Bytef*>(outbuffer); 
     zs.avail_out = sizeof(outbuffer); 

     ret = deflate(&zs, Z_FINISH); 

     if (outstring.size() < zs.total_out) { 
      // append the block to the output string 
      outstring.append(outbuffer,zs.total_out - outstring.size()); 
     } 
    } 
    while (ret == Z_OK); 

    deflateEnd(&zs); 

    if (ret != Z_STREAM_END) {   // an error occurred that was not EOF 
     std::ostringstream oss; 
     oss << "Exception during zlib compression: (" << ret << ") " << zs.msg; 
     throw(std::runtime_error(oss.str())); 
    } 

    return outstring; 
} 


/* Reads a file into memory. */ 
bool loadBinaryFile(const std::string& filename, std::string& contents) { 
    // Open the gzip file in binary mode 
    FILE* f = fopen(filename.c_str(), "rb"); 
    if (f == NULL) 
     return false ; 

    // Clear existing bytes in output vector 
    contents.clear(); 

    // Read all the bytes in the file 
    int c = fgetc(f); 
    while (c != EOF) { 
     contents += (char) c ; 
     c = fgetc(f); 
    } 
    fclose (f); 

    return true ; 
} 


int main(int argc, char *argv[]) { 
    // Read the gzip file data into memory 
    std::string fileData ; 
    if (!loadBinaryFile("myfilein.gz", fileData)) { 
     printf("Error loading input file."); 
     return 0 ; 
    } 

    // Uncompress the file data 
    std::string data ; 
    if (!gzipInflate(fileData, data)) { 
     printf("Error decompressing file."); 
     return 0 ; 
    } 

    // Print the data 
    printf("Data: \""); 
    for (size_t i=0; i<data.size(); ++i) { 
     printf("%c", data[i]); 
    } 
    printf ("\"\n"); 


    std::string outy; 
    // Compress the file data 
    outy = compress_string(data, 0); 

    //Write the gzipped data to a file. 
    FILE *handleWrite=fopen("myfileout.gz","wb"); 
    fwrite(outy,sizeof(outy),1,handleWrite); 

    fclose(handleWrite); 

    return 0; 
} 

答えて

0

std::stringvoid*(何fwriteを期待)にキャストすることはできません。

試してみてください。

fwrite(outy.data(),outy.size(),1,handleWrite); 

私はstd::string内のバイナリデータを格納することは良い考えであるかはわからないが。

+0

なぜstd :: stringにバイナリを格納するのが悪い考えがあるのが大好きですか? –

+0

うまく動作しても、良いコードは自己記述的です。 'std :: string'はある種のセマンティックを持ちます("私は人間が読める、ヌル終端のテキストを保持します ")。 'std :: vector 'は、その観点から見ればよりクリーンな選択肢になります。 – rustyx