c++ - How can I check if the first three bytes of a std::vector<uint8_t> are "G", "E&am

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

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.

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.

Share Improve this question asked Feb 2 at 20:48 user2138149user2138149 17.8k30 gold badges150 silver badges297 bronze badges 10
  • 2 I would write a function starts_with_GET, and then don't worry if the implementation isn't all that readable. The call starts_with_GET(buffer) would still be understood. – BoP Commented Feb 2 at 21:06
  • &(*recv_buffer.cbegin()) -- Is this just an overly complex way to get recv_buffer.data()? – JaMiT Commented Feb 2 at 21:15
  • @JaMiT yes it is - I somewhat prefer it because you can add to an iterator in a safe way, and there is an iterator to the end of the vector, cend. – user2138149 Commented Feb 2 at 21:26
  • @user2138149 "because you can add to an iterator in a safe way" -- How is this safer than adding to a pointer, given that contiguous storage is guaranteed? – JaMiT Commented Feb 2 at 21:30
  • 1 Some iterators of some implementations might be bounds checked, depending on your compiler and settings. The only thing the standard guarantees checking for is the at() function. – Mark Ransom Commented Feb 2 at 21:42
 |  Show 5 more comments

2 Answers 2

Reset to default 4

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*.

An alternative method is to use std::equal.

const std::string GET("GET");
if(recv_buffer.size() >= 3) {
    if(std::equal(GET.cbegin(), GET.cend(), recv_buffer.cbegin())) {
        // something
    }
}

This is not a direct answer to the question, but I thought it worth suggesting as an alternative solution.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745256968a4619016.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信