0

データをバイナリファイルに正しく正しくする方法を理解しようとしています。データは書き込まれていますが、テストのために読み戻されたときに、正しく書き込まれていないことは明らかです。データは次のように読み書きされます。

Unsigned Charは、次の文字列の長さを示し、次に文字列が書き込まれ、次に整数IDが書き込まれます。(または長さstudentname student_id)。以下は、データをファイルに保存するprintList関数です。

void printList(struct node * nptr, string filename){
  ofstream myfile;
  myfile.open( filename.c_str(), ios::binary );

  while(nptr){

  myfile.write( (char*) &nptr->data.len, sizeof( unsigned char ) );
  myfile.write( (char*) nptr->data.name, len * sizeof(char) );
  myfile.write( (char*) &nptr->data.id, sizeof(int) );

 //myfile.write( (const char*) &nptr->data, sizeof( Student ) );

 nptr = nptr->next;
}

myfile.close();

}

データがリンクリストに保存される学生の構造体は次のとおりです。

struct node{
Student data;
struct node* next;
};

//=== Student struct===//
 struct Student{
    unsigned char len;
char* name;
int id;
};
//====================//

これが私がバイナリを読み戻すために書いたloadbinファイルです。これもまた何かを台無しにしていて、これに関するたくさんのチュートリアルを読んで見ました。私は本当に困惑しています。

unsigned char len;
char* name;
int id;

int main( int argc, char* argv[] )
{
    if( argc > 1 )
    {
        ifstream f( argv[1] , ios::binary);

        while( !f.eof() )
        {
            f.read( (char*) &len , sizeof( unsigned char ) );

            if( f.eof() )
                break;

        name = new char[len+1];
        name[len+1] = '\0';

        f.read( (char*) name , len * sizeof( char ) );
        f.read( (char*) &id , sizeof( int ) );

        cout << (int)len << " " << name << " " << id 
                                            << "\n";
        }
    }

   else
        cout << "\nToo few arguments.\n";

}

さらに詳しい情報ですが、ファイルの読み込み方法を変更することはできません。修正は、書き込み時に行う必要があります。それが役立つ場合に備えて、それを含めました。

4

2 に答える 2

1

まず、最後lenのコード セグメントなどのどこかに変数が浮かんでいない限り、これがコンパイルされるかどうかさえわかりません。

myfile.write( (char*) nptr->data.name, len * sizeof(char) ); // len, what len?

sizeof(char)は常に 1 であり、可能な限り明示的な式を好むので、3 つの出力行を次のように書き直します。

myfile.write ((const char *)(&(nptr->data.len)), 1);
myfile.write ((const char *)(nptr->data.name), nptr->data.len);
myfile.write ((const char *)(&(nptr->data.id)), sizeof(int));

それを使用する方法を示す完全なプログラムは次のとおりです。これは役立つほど似ていますが、自分の仕事としてそのまま渡すことはできないほど十分に異なります:-)

#include <iostream>
#include <fstream>

struct Student {
    unsigned char len;
    char *name;
    int id;
};

struct node {
    Student data;
    struct node *next;
};

int main (void) {
    // Create dummy list, two nodes.

    node *temp = new node();
    temp->data.len = 6;
    temp->data.name = (char *)"diablo";
    temp->data.id = 2;
    temp->next = NULL;

    node *shortList = new node();
    shortList->data.len = 3;
    shortList->data.name = (char *)"pax";
    shortList->data.id = 1;
    shortList->next = temp;

    // Write it out.

    std::ofstream myfile;
    myfile.open ("xyzzy.bin", std::ios::binary);
    node *curr = shortList;
    while (curr != NULL) {
        myfile.write ((const char *)(&(curr->data.len)), 1);
        myfile.write ((const char *)(curr->data.name), curr->data.len);
        myfile.write ((const char *)(&(curr->data.id)), sizeof(int));
        curr = curr->next;
    }
    myfile.close ();

    return 0;
}

そのプログラムを実行してから 16 進ダンプを実行すると、次のようになります。

addr  +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +a +b +c +d +e +f  0123456789abcdef
----  -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --  ----------------
0000  03 70 61 78 01 00 00 00 06 64 69 61 62 6c 6f 02  .pax.....diablo.
0010  00 00 00                                         ...
0013

あなたが望んでいたフォーマットと一致すると思います。

于 2012-04-12T03:56:31.130 に答える
0

ファイルの内容についての手がかりがなければ、デバッグするのは困難ですが、物事が完全に明確であることを確認するようにしてください。

それよりも

  myfile.write( (char*) &nptr->data.len, sizeof( unsigned char ) );
  myfile.write( (char*) nptr->data.name, len * sizeof(char) );
  myfile.write( (char*) &nptr->data.id, sizeof(int) );

エラーが発生しにくくなります(行の長さの範囲内に保つためにスペースを絞り出しました):

  myfile.write((char*)&nptr->data.len, sizeof(nptr->data.len) );
  myfile.write((char*)nptr->data.name, nptr->data.len*sizeof(nptr->data.name[0]));
  myfile.write((char*)&nptr->data.id, sizeof(nptr->data.id) );

同様の式を使用して、データが読み戻されたときにデータを解凍します。変数でsizeofを使用する方が、型名を使用するよりも堅牢です。

于 2012-04-12T04:04:00.380 に答える