2017-02-25 12 views
0

ほとんどの場合、例えばcoutのようなostreamオブジェクトにそのクラスを供給したいときに、friendにすることでオーバーロードします。しかし、私にとってはそうではありません。<<を使用してクラスにファイルオブジェクトを供給するためにoperator <<を使用するにはどうすればよいですか?

std::fstream fileobj(".\example.file", std::ios::in | std::ios::binary); 
AraHaan::hexstream hexstrm; 
hexstrm << fileobj; //<-- itterates through the file object and hex arrays the data in it. 

問題は、私はこれを行うことができるかわからないです。私は私がこのような何かをやらせることができますoperator<<の過負荷を必要としています。次のようにhexstreamの現在のクラスのコードは次のとおりです。

#ifndef HEXSTREAM_DEFINED 
#define HEXSTREAM_DEFINED 
#include "basic_hexstream" 

namespace AraHaan { 
    class hexstream: public AraHaan::basic_hexstream { 
    }; 
} 

#endif 

basic_hexstream

#ifndef BASIC_HEXSTREAM_DEFINED 
#define BASIC_HEXSTREAM_DEFINED 
#include <sstream> 
#include <iomanip> 

namespace AraHaan { 
    class basic_hexstream { 
    private: 
     std::stringstream base_hexstream; 
     bool data_cleared; 
     bool append0x, writehexseparater; 
    public: 
     void AddCharacter(int character) { 
      data_cleared = false; 
      if (append0x) { 
       if (writehexseparater) { 
        base_hexstream << "0x" << std::uppercase << std::setfill('0') << 
         std::setw(2) << std::hex << static_cast<unsigned short>(character) << ", "; 
       } else { 
        base_hexstream << "0x" << std::uppercase << std::setfill('0') << 
         std::setw(2) << std::hex << static_cast<unsigned short>(character); 
      } 
      } else { 
       if (writehexseparater) { 
        base_hexstream << std::uppercase << std::setfill('0') << 
         std::setw(2) << std::hex << static_cast<unsigned short>(character) << ", "; 
       } else { 
        base_hexstream << std::uppercase << std::setfill('0') << 
         std::setw(2) << std::hex << static_cast<unsigned short>(character); 
       } 
      } 
     } 
     void setoptions(bool append_0x, bool writehexseparator) { 
      append0x = append_0x; 
      writehexseparater = writehexseparator; 
     } 
     const std::string str() { 
      return base_hexstream.str(); 
     } 
     void clear() { 
      data_cleared = true; 
      base_hexstream.clear(); 
      base_hexstream.str(""); 
     } 
     /* 
     TODO: make this work for ifstream, fstream, and FILE* file objects. 
     ex. 
      std::fstream fileobj(".\example.file", std::ios::in | std::ios::binary); 
      AraHaan::hexstream hexstrm; 
      hexstrm << fileobj; //< itterates through the file object and hex arrays the data in it. 
     */ 
     void operator<< (void* cool) {} 
     void operator<< (int character) { 
      // Note: Clearing the hexstream after every character is the user's responsibility 
      //  if ran in a for loop that can dublicate the information that is if the data from 
      //  the hexstream is obtained and added to a string after every itteration. 
      AddCharacter(character); 
     } 
     basic_hexstream() {} 
     ~basic_hexstream() { 
      // clears the data just in case. 
      // This makes clearing this manually optional. 
      if(!data_cleared) { 
       clear(); 
      } 
     } 
    }; 
} 

#endif 

しかし、ええ、私は、これは正しい動作させるためにbasic_hexstreamクラスで、このために適切にオペレータ< <を実装する必要があります何らかの形でファイルオブジェクトだけでなく、誰かがintにキャストされたキャラクターを渡すときにも起こります。 上記の例のように< < <をhexstreamクラスにファイルオブジェクトとして入力するにはどうすればよいですか?また、必要な作業をすべて実行できますか?

+0

"私はこのようなことをさせることができる演算子<<のオーバーロードが必要です:"あなたはそれをする必要はほとんどありません。名前を付けられた関数を使って、あなたが望むものを何でもすることができますが、これははっきりしません。他のiostream機能と統合したい場合は、演算子<<をオーバーロードする必要があります。これは、あなたのhexstreamクラスが関係していないためです。 –

+0

私が望むのは、明示的に "AddCharacter"を呼び出さずにint文字をヘキサストリームに渡すための '' operator << ''だけでなく、毎回渡す前にファイルの反復を行うファイルオブジェクトを渡すためのバージョン文字は '' int''から '' AddCharacter''にキャストされます。基本的には長い話です。私は、人々が16進エディタのようなものに必要なファイル全体の内容を16進数で配列したいときに、すべてのファイルの反復処理を行うことができるようにしたいと考えています。だから基本的にはそれは可能な限り人々のコードをソートすることができますが、同じことを行うことができます – user2151283

+0

何かがこの質問から欠落しているようです。それは実際の質問でしょう。ここに述べられている唯一のものはあなたが必要とするものです。それは問題ではありません。ここで書いた内容を編集し、具体的で簡潔な質問を追加する必要があります。 "私はこれを必要とし、私はそれが必要です"という長文の小説は、オフトピックですstackoverflow.com –

答えて

0

これらの方法のいずれかを使用できます。以下に、fstreamからデータを取り出してコンソールに出力する単純なストリームの2つの例を示します。

例1(オペレータ< <メンバ関数)

#include <iostream> 
#include <string> 
#include <fstream> 

using namespace std; 

class TextStream 
{ 
public: 
    string getText() const; 
    TextStream& operator<<(fstream& stream); 

private: 
    string text; 
}; 

string TextStream::getText() const 
{ 
    return text; 
} 

TextStream& TextStream::operator<<(fstream& stream) 
{ 
    while (true) 
    { 
     string line; 
     if (!std::getline(stream, line)) break; 
     line += '\n'; 
     text += line; 
    } 

    return *this; 
} 

int main(int argc, char **argv) 
{ 
    fstream file1("temp1.txt"); 
    fstream file2("temp2.txt"); 

    TextStream ts; 
    ts << file1 << file2; 
    cout << ts.getText() << endl; 

    file1.close(); 
    file2.close(); 

    return 0; 
} 

例2(オペレータ< <フレンド関数)

#include <iostream> 
#include <string> 
#include <fstream> 

using namespace std; 

class TextStream 
{ 
public: 
    string getText() const; 
    void append(const string& s); 

    friend TextStream& operator<<(TextStream& textStream, fstream& fileStream); 

private: 
    string text; 
}; 

string TextStream::getText() const 
{ 
    return text; 
} 

void TextStream::append(const string& s) 
{ 
    text += s; 
} 

TextStream& operator<<(TextStream& textStream, fstream& fileStream) 
{ 
    while (true) 
    { 
     string line; 
     if (!std::getline(fileStream, line)) break; 
     line += '\n'; 
     textStream.append(line); 
    } 

    return textStream; 
} 

int main(int argc, char **argv) 
{ 
    fstream file1("temp1.txt"); 
    fstream file2("temp2.txt"); 

    TextStream ts; 
    ts << file1 << file2; 
    cout << ts.getText() << endl; 

    file1.close(); 
    file2.close(); 

    return 0; 
} 
+0

ええ、助けてください。ありがとう、 – user2151283

+0

それのすべての後に。これは新しい '' basic_hexstream''クラスの始まりです。 https://godbolt.org/g/YWSi5o – user2151283

1

私はこれをやろうとしていた場合、私はむしろを取りたいです異なるアプローチ。私たちは、その後できる

class hex_buf : public std::streambuf { 
    std::streambuf *buffer; 
    bool use_prefix; 
public: 
    typedef std::char_traits<char> traits_type; 
    typedef traits_type::int_type int_type; 

    hex_buf(std::ostream &os, bool use_prefix) : buffer(os.rdbuf()), use_prefix(use_prefix) {} 

    int_type overflow(int_type c) { 
     static const char chars[] = "abcdef"; 

     if (use_prefix) { 
      buffer->sputc('0'); 
      buffer->sputc('x'); 
     } 
     unsigned char ch = (unsigned char)c; 
     buffer->sputc(chars[ch >> 4]); 
     return buffer->sputc(chars[ch & 0xf]); 
    } 
}; 

代わりに全体の流れのようなクラスを書いて、それが既存のストリームと互換性がない可能性があると、私は通過途中で進にデータを変換streambufクラスをフィルタリング書きたいです

class hex_stream : public std::ostream { 
    hex_buf output; 
public: 
    hex_stream(std::ostream &os, bool use_prefix = false) : output(os, use_prefix), std::ostream(&output) {} 
}; 

は今、私はその先として既存のostreamを取るためにhex_streamを書いた:ミックスにそのフィルタリングたstreambufを既存のストリームに接続するが、追加ストリームクラスを作成します。必要に応じて、ostream自体を構築するのは簡単です(たとえば、名前を渡してfstreamを構築するか、何も渡さずに文字列ストリームを構築します)。他のいくつかのストリームをコピーし、これにより

hex_stream s(std::cout); 
    s << "1234"; 

    hex_stream t(std::cout, true); 
    t << "1234"; 

:私達はちょうどhex_streamを使用して、いくつかの既存のストリームに添付 -

これを使用するには、我々は(通常は)直接 hex_bufクラスを使用していませんあなたは物事をこの方法でやってみたいと思います理由として

hex_stream h(std::cout); 
std::ifstream infile("test.txt"); 

h << infile.rdbuf(); 

    ストリームのこのタイプは、我々は、他のストリームでそれを行うだろうと同じように行うことができますへ
  1. コードは実際には短く簡単です。
  2. 結果は実際のostreamです。したがって、既存のostreamで動作するすべてのものが本来のostreamとともに動作します。たとえば、無数の既存のストリーム挿入演算子を考えてみましょう。

    hex_stream ss(std::cout, true); 
    
    foo f{ 1, false }; 
    
    ss << f; 
    

    は出力を生成します:この場合0x310x2c0x200x660x610x6c0x730x65

    、例えば、このような何か:それはここで定義されていますよう

    struct foo { 
        int a; 
        bool b; 
    
        friend std::ostream &operator<<(std::ostream &os, foo const &f) { 
         return os << std::boolalpha << f.a << ", " << f.b; 
        } 
    }; 
    

これはhex_streamでうまく動作します0x31は1、0x2cはカンマ、0x20はスペース、0x660x610x6c0x730x65はISO-8859エンコーディングのfalseであり、i nは16進数です。

つまり、既存のストリーム挿入演算子だけでなく、ユーザー提供のオーバーロードされた挿入演算子も機能します。したがって、(std::boolalphaで示すように)既存のストリームマニピュレータを実行します。

この問題を解決するには、もう少し正しい方法があります。フィルタリングストリームバッファを作成する代わりに、出力を16進数としてエンコードするcodecvtファセットを作成できます。これはすでにかなり長い投稿ですので、私は今すぐそのコードを含めることを控えます。

関連する問題

 関連する問題