2

I declared a large character array and then I subsequently read from a socket to populate it.

boost::array<char, 32841> buf{}
size_t len = boost::asio::read(socket, aio::buffer(buf, 32841));

If I print out len I correctly get 32841 and when I loop through all the character in the array individually, like so,

for (char i : buf) {
    std::cout << i << std::endl;
}

I get an output for each character. However, when I try to print out the string form of my buffer (via buf.data()), things don't work as I would like them to. I don't get all the characters to print out -- only around 20 characters print out.

I am reading a bunch of encrypted junk (for example, �Q{��=� �o$9�ZC �kL) into the buffer which means that there is the possibility to get chars that encode all sorts of funky characters like null bytes, new lines, etc. Could this be my issue? Does .data() stop string conversion at null bytes or some other weird character?

peachykeen
  • 4,143
  • 4
  • 30
  • 49
  • 2
    `std::cout << buf.data()` will indeed stop display at first `\0` in your buffer. – Jarod42 Dec 06 '19 at 21:30
  • In which case, you can use `std::cout.write(buf.data(), len)` instead – Remy Lebeau Dec 06 '19 at 21:31
  • @RemyLebeau thx for the fixes and thanks for `std::cout.write` I had some surprises with `std::string`s containing null-characters and didnt know about `cout.write` – 463035818_is_not_an_ai Dec 06 '19 at 21:36
  • @formerlyknownas_463035818 A `std::string` would work too, at the cost of a dynamic memory allocation (unless `len` fits in the string's SSO buffer, if present): `std::cout << std::string(buf.data(), len)` – Remy Lebeau Dec 06 '19 at 21:38

2 Answers2

4

boost::array<char, N>::data() (and std::array<char, N>::data()) returns a const char*. Passing this pointer to std::cout << will assume a null-terminated string, hence the output will stop at the first \0 character encountered.

To see the full data, use std::cout.write(buf.data(), len) instead.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
1

basic_ostream<CharT,Traits>& operator<<( basic_ostream<CharT,Traits>& os, const CharT* s )

outputs s as null-terminated c-string.

you might use:

  • std::cout.write(buf.data(), len)
  • std::cout << std::string_view{buf.data(), len} (or alternative using std::string but would probably allocate)
Jarod42
  • 203,559
  • 14
  • 181
  • 302