Search code examples
c++c++23

How can I check if the first three bytes of a std::vector<uint8_t> are "G", "E", "T"?


I want to check if a std::vector<uint8_t> recv_buffer starts with the string "GET".

The simplest way to do it would be to check each of the first 3 bytes individually. However, this does not produce a very readable code.

I tried to create a std::string_view from a std::vector but could not figure out how to do this in a way which did not involve a complex statement involving pointer casts.

My objective was to compare the string_view against "GET".

I thought that I might be able to make a 3 byte/character long string_view object which referenced the first 3 bytes of a vector. But it doesn't look like there is a way to do that.

Maybe a span object could be used as an intermediary or something? But it doesn't look like a string_view can be constructed from a span easily.

I tried this

if(recv_buffer.size() >= 3) {
    std::string_view view(static_cast<const char* const>(&(*recv_buffer.cbegin())), 3);
    if(view == "GET") {
        // something
    }
}

but that produces an invalid static_cast error. reinterpret_cast will work, but I am not sure that doing a bunch of hacky pointer casts is a good solution.


Solution

  • There's an algorithm for that: starts_with():

    if (std::ranges::starts_with(recv_buffer, "GET"sv))
    

    Note that you specifically have to do "GET"sv, not "GET". The latter will compile but unfortunately do the wrong thing, since "GET" is a char const[4] — so that would check that not only are the first three characters in recv_buffer equal to GET but also that the 4th is \0.


    An alternative approach is to use the string_view on the other side. string_view is explicitly constructible from any suitable contiguous, random-access range:

    if (std::string_view(recv_buffer).starts_with("GET"))
    

    Here, just using "GET" is fine, since there is a specific overload for char const*.