0

ファイルに C 構造体を書き込んで (バイナリで書き込む)、それを読み取って復元しようとしています。それが可能かどうかはわかりません。これが私が持っているものです:

head.hh:

#include <iostream>

typedef struct s_test
{
  char  cmd[5];
  std::string   str;
}t_test;

main.cpp:

#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "head.hh"

int     main()
{
  t_test        test;
  int   fd = open("test", O_APPEND | O_CREAT | O_TRUNC | O_WRONLY, 0666);

  test.cmd[0] = 's';
  test.cmd[1] = 'm';
  test.cmd[2] = 's';
  test.cmd[3] = 'g';
  test.str = "hello world";
  write(fd, &test, sizeof(t_test));


  close(fd);
  fd = open("test", O_APPEND | O_CREAT | O_WRONLY, 0666);

  t_test        test2;

  read(fd, &test2, sizeof(t_test));
  std::cout << test2.cmd << " " << test2.str << std::endl;

  return (0);
}

そして、出力には次のようなものがあります。

4

2 に答える 2

1

読み取り元のファイルが書き込み専用として開かれていました。

実際のstd::stringオブジェクトはそのように書くことはできません。実際のオブジェクトには通常、2 つのポインターとおそらくサイズが含まれますが、実際の文字データは含まれません。シリアル化する必要があります。

C++ を作成する場合は、ここで得たものではなく、ファイル ストリームの使用方法を学習することを検討する必要があります。

#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <io.h>
#include <iostream>
#include <string>
#include <vector>

typedef struct s_test
{
    char cmd[5];
    std::string str;
}t_test;

void Write(int fd, struct s_test* test)
{
    write(fd, test->cmd, sizeof(test->cmd));
    unsigned int sz = test->str.size();
    write(fd, &sz, sizeof(sz));
    write(fd, test->str.c_str(), sz);
}

void Read(int fd, struct s_test* test)
{
    read(fd, test->cmd, sizeof(test->cmd));
    unsigned int sz;
    read(fd, &sz, sizeof(sz));
    std::vector<char> data(sz);
    read(fd, &data[0], sz);
    test->str.assign(data.begin(), data.end());
}

int main()
{
    t_test test;
    int fd = open("test", O_APPEND | O_CREAT | O_TRUNC | O_WRONLY, 0666);

    test.cmd[0] = 's';
    test.cmd[1] = 'm';
    test.cmd[2] = 's';
    test.cmd[3] = 'g';
    test.cmd[4] = 0;
    test.str = "hello world";
    std::cout << "Before Write: " << test.cmd << " " << test.str << std::endl;

    Write(fd, &test);
    close(fd);

    fd = open("test", O_RDONLY, 0666);
    t_test test2;
    Read(fd, &test2);
    std::cout << "After Read: " << test2.cmd << " " << test2.str << std::endl;
    close(fd);

    return (0);
}
于 2013-11-14T20:07:07.350 に答える
0

たとえば、構造体をバイナリ ファイルにダンプすると、メモリ内イメージがディスクに書き込まれます。

class X
{
public:
    int i;
    int j;
};

. . .

X lX;
lX.i= 10;
lX.j = 20;

クラス lX のオブジェクトは、バイナリ ファイルに書き込まれると |10|20| のようになります。つまり、読むときはうまくいきます。

ただし、文字列のようなポインターを含むクラスの場合。

class Y
{
public:
    int* pi;
    int j;
};

. . .

Y lY;
lY.pi= new int(10); // lets assume this is created at memory location 1001
lY.j = 20;

そのため、オブジェクト lY の pi の値は 1001 になります (ポインターであるため、10 ではありません)。lY をバイナリ ファイルに書き込むと、 |10001|20| のようになります。そして、それを読み返すと、値 pi が 1001 で j が 20 である Y の新しいオブジェクト (lY2 など) が構築されます。答えはゴミです。それはあなたが画面上で見ているものです。Linux ではセグメンテーション違反が発生するため、Windows を使用してこれを実行していると思います。

于 2013-11-14T18:43:01.600 に答える