4

I have a character range with pointers (pBegin and pEnd). I think of it as a string, but it is not \0 terminated. How can I print it to std::cout effectively?

  • Without creating a copy, like with std::string
  • Without a loop that prints each character

Do we have good solution? If not, what is the smoothest workaround?

2
  • What's wrong with the copy from std::string( pBegin, pEnd )? That's the natural way of doing it (and the copy won't be noticeable compared to the time taken by the actual output). Commented Jul 12, 2013 at 11:27
  • The answer is very useful for me. Maybe I transformed the question too much from the original problem and should have asked about std::ostream, which can be std::stringstream. where the difference may count. Commented Jul 12, 2013 at 11:37

2 Answers 2

10

You can use ostream::write, which takes pointer and length arguments:

std::cout.write(pBegin, pEnd - pBegin);
Sign up to request clarification or add additional context in comments.

Comments

8

Since C++17 you can use std::string_view, which was created for viewing part of a character buffer without copying.

std::cout << std::string_view(pBegin, pEnd - pBegin);

pEnd must point to one past the last character to print, like how iterators in C++ work, instead of the last character to print.

In older C++ standards boost::string_ref is an alternative. Newer boost versions also have boost::string_view with the same semantics as std::string_view. Newer C++ standard also has std::span which is a little bit similar in purpose. See Differences between boost::string_ref and boost::string_view.

If you use Qt then there's also QStringView and QStringRef although unfortunately they're used for viewing QString which stores data in UTF-16 instead of UTF-8 or a byte-oriented encoding.


However if you also need to process the string by some functions that require null-terminated string without any external libraries then there's a simple solution (assuming your string is modifiable):

char tmpEnd = *pEnd;  // backup the after-end character
*pEnd = '\0';
std::cout << pBegin;  // use it as normal C-style string, like dosomething(pBegin);
*pEnd = tmpEnd;       // restore the char

In this case make sure that pEnd still points to an element inside the original array and not one past the end of it.

In fact I've just found out that busybox grep also uses that technique to print out the matches without allocating more memory.


See also How do I print a string between two pointers?, which addresses a similar problem in the C language.

Comments

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.