there is a structure

struct Record { int Score; UnicodeString Name; }; 

there is a vector

  std::vector<Record> list; 

code to write structure to file

 std::ofstream out("output.txt", std::ios::out | std::ios::binary); std::vector<Record>::size_type size = list.size(); out.write((char*)&list, sizeof(size)); out.write((char*)&list[0], list.size() * sizeof(Record)); out.close(); 

read code

 std::ifstream is("output.txt", std::ios::in | std::ios::binary); std::vector<Record>::size_type size = 0; is.read((char*)&size, sizeof(size)); list.resize(size); is.read((char*)&list[0], list.size() * sizeof(Record)); is.close(); 

the problem is that the data is either not recorded (although there are changes in the file, but since it is binary it is difficult to determine what was recorded), or it is not readable (which is more likely because the new vector has size 0)

UnicodeString is a string type (all components usually in text properties accept / return a given type). I do the project in RAD Studio 10.2

  • Explain what the problem is. What is UnicodeString ? - Cerbo
  • @Cerbo added to the description - Alexandr

1 answer 1

You are not doing everything right.

First, here you are not writing the size, but the first sizeof(size) bytes of the list object:

 out.write((char*)&list, sizeof(size)); 

apparently meant:

 out.write((char*)&size, sizeof(size)); 

By the way, to call a vector object named list , to put it mildly, is not a good idea.

Secondly, the recording and reading of the elements themselves are also not correct. We analyze your expression:

 out.write((char*)&list[0], list.size() * sizeof(Record)); 
  1. (char*)&list[0] here you get a pointer to the first element of the array and lead it to a pointer to char , to the article if you don’t check the size of the vector above and if it is empty, then an exception will be thrown here;
  2. list.size() * sizeof(Record) define the size of the array in bytes, this is correct;
  3. the stream writes a continuous block of bytes of the size list.size() * sizeof(Record) starting from the address (char*)&list[0] , while the raw bytes are taken directly from the memory without parsing ;

In this case, the Score field is written correctly because it has a simple numeric type. But the Name field is recorded not as you seem to expect. A byte copy is written directly to the fields of the UnicodeString object, not bytes of a string. The UnicodeString object does not contain the bytes of the string, but only a pointer to the memory where they are located.

To write UnicodeString correctly, you need to get a pointer to a block of memory where the string is directly stored (this is done using the UnicodeString::data() function UnicodeString::data() ), correctly calculate the size of the string in bytes, and write in this form. Separately, you need to handle blank lines.

Reading must be done in the reverse order: you read the bytes of the string into the intermediate buffer, and then pass this buffer to the UnicodeString constructor.