2013年4月4日木曜日

c++ でファイルダンプ(クラス風味)

c++ のファイルダンププログラムもクラス風味にしてみました。c++ でも例外処理はサポートしているものの標準クラスライブラリではこの仕組みが使われていない。どうも、C言語とC++の棲み分けが曖昧で解りづらい印象が拭いきれない。Dump d(argv[1])も Dump d(new string(argv[1])) だとエラーになるのもなんだか釈然としないままです。
#include <fstream>
#include <string>
#include <iostream>
#include <boost/format.hpp>
using namespace std;
using boost::format;

class Dump
{
private:
    string file;
    char buf[17];
    int  cnt;
    int  error;
public:
    Dump(string s) {
        file = s;
        cnt  = 0;
        error = 0;
        std::fill_n(buf,sizeof(buf),'\0');
    }

    void adrdump(int adr) {
        cout << format("%08x : ") % adr;
    }

    void hexdump(unsigned char *buf, int size) {
        string out;
    
        for(int i=0;i<size;i++) {
            if (i == 8) { out += "- "; }
            out += (format("%02x ") % (int)buf[i]).str();
        }
        cout << format("%-50s") % out;
    }

    void chrdump(unsigned char *buf, int size) {
        string out;
    
        for(int i=0;i<size;i++) {
            out += (0x00 <= buf[i] && buf[i] <= 0x1f) || 0x7f <= buf[i] 
                ? "." : (format("%c") % buf[i]).str();
        }
        cout << format("| %-16s") % out;
    }

    int display() {

        error = 0;
        ifstream ifs(file.c_str());
        if (!ifs.is_open()) {
            cerr << format("Can't open file[%s]\n") % file;
            return(false);
        }
        while(!ifs.eof()){
            std::fill_n(buf,sizeof(buf),'\0');
            ifs.read((char *)&buf, sizeof(buf)-1 );
            if (ifs.bad()) {
                cerr << format("Read failed\n"); 
                return(false);
            }
    
            adrdump(cnt*16);
            hexdump((unsigned char *)buf,ifs.gcount());
            chrdump((unsigned char *)buf,ifs.gcount());
            cout << endl;
     
            cnt++;
        }
        ifs.close();
    }
};

int main(int argc, char *argv[])
{
    if (argc!=2) {
        cerr << format("Usage : test02 file\n"); 
        return(1);
    }

    Dump d(argv[1]);
    if (!d.display()) {
        cerr << format("Display error\n"); 
        return(EXIT_FAILURE);
    }
    return(EXIT_SUCCESS);
}

0 件のコメント:

コメントを投稿