这是在C++中读入字符串的好习惯?

发布于 2025-02-09 15:47:53 字数 1142 浏览 3 评论 0原文

我在C ++中有一个功能,该功能将HTTP请求的内容读取 body std :: string。 我提出了以下代码:

void handle_request_body(int connfd, HttpRequest &req) {
  unsigned long size_to_read;
  try {
    size_to_read = std::stoul(req.headers().at("content-length"));
  } catch (std::out_of_range const &) {
    return;
  }
  char *buf = new char[size_to_read + 1];
  memset(buf, 0, size_to_read + 1);
  read(connfd, buf, size_to_read);
  req._body.append(buf);
  delete[] buf;
}

这对我来说有点丑陋,因为我必须使用new,因为不允许使用变量大小的数组。 然后,我尝试将直接读取到字符串中,而不是以下代码:

void handle_request_body(int connfd, HttpRequest &req) {
  unsigned long size_to_read;
  try {
    size_to_read = std::stoul(req.headers().at("content-length"));
  } catch (std::out_of_range const &) {
    return;
  }
  std::string buf(size_to_read + 1, 0);
  read(connfd, buf.data(), size_to_read);
  req._body = buf;
}

我发现第二种方法更清洁,但是我担心直接读取到std :: string 使用其data()方法。

有更好的方法吗? 任何见解都非常感谢!

I have a function in C++ which reads the contents of a HTTP request body into a std::string.
I came up with the following code:

void handle_request_body(int connfd, HttpRequest &req) {
  unsigned long size_to_read;
  try {
    size_to_read = std::stoul(req.headers().at("content-length"));
  } catch (std::out_of_range const &) {
    return;
  }
  char *buf = new char[size_to_read + 1];
  memset(buf, 0, size_to_read + 1);
  read(connfd, buf, size_to_read);
  req._body.append(buf);
  delete[] buf;
}

This is a little ugly to me as I have to use new since variable-sized arrays are not allowed.
I then tried to read directly to a string instead with the following code:

void handle_request_body(int connfd, HttpRequest &req) {
  unsigned long size_to_read;
  try {
    size_to_read = std::stoul(req.headers().at("content-length"));
  } catch (std::out_of_range const &) {
    return;
  }
  std::string buf(size_to_read + 1, 0);
  read(connfd, buf.data(), size_to_read);
  req._body = buf;
}

I find the second method much cleaner, but I'm worried as to whether it is considered bad practice to read directly into a std::string using its data() method.

Is there a better way to do this?
Any insight is much appreciated!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

最后的乘客 2025-02-16 15:47:53

确实取决于您的阅读功能在引擎盖下的作用。

如果您可以控制读取功能,我强烈建议您不使用指针,而是对STD容器的类引用。
可解析的STD容器不能保证指针将继续指向相同的内存,即如果它重新关注其大小,则指针将不再有效。在此示例中很好,因为没有其他人触摸它,但是在许多其他应用程序中,这将是极其不安全的!

类似:

void read(int id, std::string& dest, int readLength){
      //whatever code gets the data stream
      dest += data;
}

如果必须是某些OS API调用的C风格缓冲区,最好使用独特的字符指针,以便让内存自身清理。

 std::unique_ptr<char[]> buffer = std::make_unique<char[]>(size + 1);
 memset(&buffer[0], 0, size + 1);

我不建议您从Char的OS Char上阅读,因为这通常每次通话都有巨大的性能开销,而不是一次阅读。

Really depends what your read function does under the hood.

If you have control over the read function, I strongly suggest you don't use a pointer, but rather a class reference to a std container.
The resizable std containers don't guarantee that the pointers will keep pointing at the same memory i.e. if it reallocates it's size, your pointer will no longer be valid. Which is fine in this example because no one else is touching it, but in a lot of other applications this would be extremely unsafe!

Something like:

void read(int id, std::string& dest, int readLength){
      //whatever code gets the data stream
      dest += data;
}

If it has to be a C-Style buffer for some OS API call probably best to use a unique pointer of chars, to let the memory clean up after itself.

 std::unique_ptr<char[]> buffer = std::make_unique<char[]>(size + 1);
 memset(&buffer[0], 0, size + 1);

I don't recommend reading from the OS char by char as this usually has a huge performance overhead for every call, compared to reading it all at once.

还在原地等你 2025-02-16 15:47:53

正如@galik评论。这是基于意见的。

但是我们可以指出的是:

  • 在C ++中,我们不应将原始指针用于拥有的内存
  • newdelete应避免使用
  • C风格数组,应避免
  • 阅读到> data()将起作用,但不是很好(我的看法)。无论如何,比使用新的并创建内存泄漏更好。

您可以,在简单的中,循环从文件中读取一个字节,然后将每个字节添加到std :: string带有+= 。但这也很笨拙。

最好的是,如果允许您使用C ++语言和库。

顺便提一句。 std :: String也是“变量大小数组”

建议:使用第二个解决方案

As @Galik commented. This is opinion based.

But what we can state is:

  • In C++ we should not use raw pointers for owned memory
  • new and delete should be avoided
  • C-Style arrays should be avoided
  • Reading into data() will work, but is not that nice (my opinion). Anyway, better than using new and creating a memory leak.

You could, in a simple for loop read one byte after the other from the file and then add each byte to the std::string with +=. But this is also very clumsy.

Best would be, if you were allowed to use C++ language and libraries.

BTW. std::string is also a "variable-sized array"

Recommendation: Go with your second solution

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文