0

私は問題に取り組んでいますが、これを適切に行っているのか、それとも正しいアプローチをとっているのかはわかりません。これまでのところ、私のコードはsegfaultsを与えてくれます。

私はいくつかのC++の概念を実践するための簡単な小さな領収書作成プログラムを持っています。そのうちの1つはバイナリのファイルI/Oです。データを保持する配列がいくつかあります(1つはサービスタイプの文字列を保持し、もう1つは対応する2倍のコストを保持します)。メニューが少しありますが、バイナリ部分での書き込みは問題ありません。ただし、ファイルからこれらを読み戻す方法がわかりません。

現在、さまざまなデータメンバー(顧客の名前、合計料金など)を保持する構造を使用しており、選択したすべてのサービスとそれに対応する価格をファイルに書き込んでから、読み取ることができるようにしたいと考えています。それらを戻します。これらは現在、構造内のベクトルに格納されています。

バイナリファイルとの間で文字列を読み書きする方法を理解していると思います(文字列の長さを書き込み、次にデータを書き込み、次に長さを読み戻し、その数のバイトを文字列に読み込みます)。しかし、ベクトルを使用してこれを行うにはどうすればよいですか?たとえば、固定サイズのメンバーのベクトル(つまり、int)を使用してそれを行う方法は理解していますが、文字列のベクトルについてはどうでしょうか。この場合、メンバーのサイズが決まっていないので、読み返し方がわかりません。

これも可能ですか?誰かが私を正しい方向に向けることができれば、それは非常に役に立ちます。1年ほど前に同様のフォーラム投稿がありましたが、あまり役に立ちませんでした。

tl; dr-バイナリファイルから可変長文字列の可変サイズベクトルを読み取るにはどうすればよいですか?

4

3 に答える 3

1

マークがhttp://www.boost.org/doc/libs/1_49_0/libs/serialization/doc/index.htmlを使用して指摘したように、データをオブジェクトにパッケージ化またはカプセル化し、それらをシリアル化する必要があります。そこに例と詳細なヘルプがあります。非常に単純なケースを検索します。:)

編集:私はあなたのために簡単で汚い例を作りました。楽しみ。(整形でごめんなさい。)

#include <cstddef> // NULL
#include <iomanip>
#include <iostream>
#include <fstream>
#include <iterator>

#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/utility.hpp>
#include <boost/serialization/assume_abstract.hpp>
#include <boost/serialization/string.hpp>
#include <boost/serialization/vector.hpp>

class family_names
{
    friend class boost::serialization::access;
    std::vector<std::string> m_names;
    template<class Archive>
    void serialize(Archive & ar, const unsigned int version)
    {
    ar & m_names;
    }

    friend std::ostream & operator<<(std::ostream &os, const family_names& fn);

    public:
family_names(const std::vector<std::string>& names)
    : m_names(names)
{}

family_names() {}
    };

    std::ostream & operator<<(std::ostream &os, const family_names& fn)
    {
std::ostream_iterator<std::string> out_it (std::cout,", ");
std::copy(fn.m_names.begin(), fn.m_names.end(), out_it);
return os;
    }

    void save(const family_names &s, const char * filename){
// make an archive
std::ofstream ofs(filename);
boost::archive::text_oarchive oa(ofs);
oa << s;
    }

    void restore(family_names &s, const char * filename)
    {
// open the archive
std::ifstream ifs(filename);
boost::archive::text_iarchive ia(ifs);

// restore the family names from the archive
ia >> s;
    }

    int _tmain(int argc, _TCHAR* argv[])
    {

std::vector<std::string> vec_names;
vec_names.push_back("Jason");
vec_names.push_back("Mark");
vec_names.push_back("Ludmilla");


family_names names(vec_names);
std::string filename = "c:\\Dev\\demofile.txt";

std::cout << names << std::endl;
save(names, filename.c_str());

family_names names_back;
restore(names_back, filename.c_str());
std::cout << names_back << std::endl;

return 0;
  }
于 2012-04-08T08:49:42.593 に答える
1

言い換えると:

> 長さを読み返し、そのバイト数をベクトルで文字列に読み込むにはどうすればよいですか?

一度に 1 つの文字列:

// Untested
std::vector<std::string> ReadSomeStrings(std::istream& inFile, size_t howMany) {
  std::vector<std::string> result;
  for(int i = 0; i < howMany; ++i) {
    std::size_t len;
    is.read(&len, sizeof len);
    std::string s(len, '\0');
    is.read(&s[0], s.size());
    result.push_back(s);
  }
  return result;
}
于 2012-04-08T09:11:08.360 に答える
0

>> と << 演算子を使用していると思いますが、バイナリ操作には ofstream::write と ifstream::read で試してみることをお勧めします。

于 2012-04-08T09:17:18.440 に答える