0

Consider the following code:

#pragma pack(2)

struct file_data {
  uint8_t data0;
  uint16_t data1;
  uint8_t data2;
}

#pragma pack()

file_data readFile(const std::string& pathFile) {
  file_data result;

  std::ifstream(pathFile, std::ios::in | std::ios::binary);
  if(!file.is_open()) return file_data();

  file.read(reinterpret_cast<char*>(result), sizeof(file_data));
  file.close();

  return result;
}

int main(int argc, char* argv[]) {
  file_data = readFile("the/path/to/the/file");

  return 0;
}

In plain English, the code reads the file to the variable result, of type struct file_data, and returns it.

However, say I have already read the bytes of a file and stored them in a std::vector of type int8_t. I want to then write that data to an instance of file_data. I do not want to do this field by field, as the structure may change.

This has been my workaround:

file_data readData(const std::vector<int8_t>& bytes) {
  std::stringstream ss;
  for(int8_t byte : bytes) ss.write(reinterpret_cast<const char*>(&byte), sizeof(int8_t));

  file_data result;
  ss.read(reinterpret_cast<char*>(&result), sizeof(file_data));

  return result;
}

So, first the vector is written back to a stream, then read into the struct.

I feel like this is highly inefficient, and there is some knowledge I am missing here. Can someone please provide a better solution to my readData() method?

2
  • 1
    You're looking for memcpy(). Commented Jan 14, 2020 at 14:20
  • @Evg Yes. I did not c+p this code and it is a typo. Commented Jan 14, 2020 at 15:04

1 Answer 1

2

Aside: int8_t might not be char, you should use it instead.

file_data readData(const std::vector<char>& bytes) {
  file_data result;
  std::copy_n(bytes.data(), sizeof(file_data), reinterpret_cast<char*>(&result));
  return result;
}

This works similarly with std::string and std::array<char, N> (for N >= sizeof(file_data))

Sign up to request clarification or add additional context in comments.

1 Comment

I didn't know std::copy_n() could be used this way. Thank you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.