1

I am writing a unit test where a string has to end in a binary zero.

Consider const char * data_c = "1234"; , here data_c contains 5 characters including a zero. std::string removes that zero and tracks the size like a vector. std::string data_cpp = "1234";

The string I need to create has a binary zero at the end. Initialising std::string with simple means seems problematic. std::string data_cpp{"ABC\0"}; Gives back a string of size 3;

The following minimal example show passing and not passing examples to illustrate my problem further:

#include <iostream>
#include <string>

void testString(std::string name, std::string str)
{
    int e = 0;
    std::cout << name << "\n";
    std::cout << "----------------------" << "\n";

    if (4 != str.size())
    {
        std::cout << "Size was not 4" << "\n";
        e += 1;
    }
    char testvals[] = {'A', 'B', 'C', '\0'};
    for (size_t n = 0; n < 4 && n < str.size(); ++n)
    {
        if (str[n] != testvals[n])
        {
            std::cout << "Character " << std::to_string(n) << " '" << str[n] << "'" << " did not match" << "\n";
            e += 1;
        }
    }
    std::cout << "ERRORS: " << std::to_string(e) << "\n";
    std::cout << "----------------------" << std::endl;
}

template<size_t N>
std::string CutomInitString(const char(&str)[N])
{
    return std::string{str, str + N - 1};
}

int main()
{
    std::string one{"ABC\0"};
    testString("ONE", one); //FAILS

    const char two_c[] = "ABC\0";
    std::string two{two_c};
    testString("TWO", two); //FAILS


    const char three_c[] = "ABC\0";
    std::string three{three_c, three_c + (sizeof(three_c) / sizeof(char)) - 1};
    testString("THREE", three); //PASS, also ugly

    const char four_c[] = "ABC\0";
    std::string four{CutomInitString(four_c)};
    testString("FOUR", four); //PASS, also ugly
}

An example for simple would be std::string one. Is there a simple form that I can use?

Johannes
  • 6,490
  • 10
  • 59
  • 108

2 Answers2

4

You could use an std::string constructor which takes the size of the buffer:

basic_string( const CharT* s,
              size_type count, 
              const Allocator& alloc = Allocator() );
SergeyA
  • 61,605
  • 5
  • 78
  • 137
1

Edit: Rewrote answer after some consideration.

The real problem here is not in std::string but actually in the built-in array type, which doesn't really work like a container. The solution below isn't much different from yours, but you might think it's less ugly if you use to_array to convert the built-in array type to std::array immediately.

auto my_array = std::experimental::to_array("ABC\0");
std::string my_string{my_array.begin(), my_array.end()};
Chris Beck
  • 15,614
  • 4
  • 51
  • 87