【问题标题】:Can we create a C++ string object from char pointer where the operations on the string object reflects to the source char pointer?我们可以从 char 指针创建一个 C++ 字符串对象,其中对字符串对象的操作反映到源 char 指针?
【发布时间】:2019-11-18 02:16:23
【问题描述】:

我一直在尝试使用 C++ 字符串类丰富的方法(find_first_of、replace)来处理某个任务的字符串。

我围绕上述代码创建了一个包装文件,它可以包含在“C”源文件中并获得功能。

strUtils.h

#ifdef __cplusplus
extern "C" {
#endif

void doTheStringWork(char *inStr, unsigned beginLoc);

#ifdef __cplusplus
}
#endif

strUtils.cpp

#include "strUtils.h"
/*some standard includes here*/

void doTheStringWork(char *inStr, unsigned beginLoc) {
    std::string inStr_s(inStr);

    /* Doing some processing with the string object inStr_s*/  
    /* .......*/
    /* Done */

    return;  

}

现在我遇到了一个问题,据我所知,如果不制作副本就无法解决。所以,我在这方面寻求你的帮助。

问题是我需要将doTheStringWork 函数完成的更改返回到调用者的位置。您可能会说将 .c_str() 值作为 func 的返回值或以某种方式获取副本。这种方法效果很好,但对于我的任务来说,它变得非常慢,因为字符串可能太长,我可能需要它递归处理。

简而言之:我们可以围绕 char 指针创建一个字符串对象,我可以在其中使用所有字符串函数,并且 char 指针反映了所有这些变化。如果使用标准库无法实现这样的事情,有人可以提供一种方法,我该如何在这里实现我的目标。

【问题讨论】:

  • 自 C++ 17 起,string_view.允许根据给定的分配数据(另一个字符串或 char*)创建字符串。然而,这是一个不可变的。
  • 除非您控制原始字符数组的分配方式,否则任何需要重新分配的解决方案都意味着您还有一个无用的数组,您不知道是否/如何释放它。
  • std::string_view 可能对你有用。
  • @SergeyA 但迈克尔告诉该对象变得不可变。而且由于其他项目限制,我已经不能使用 c++17。
  • 此外,任何执行重新分配的操作都可能使原始数据指针的副本无效(假设它甚至更新了一个特定的副本),如果您正在使用这些副本,则不太可能出现首先是裸指针。

标签: c++ string pointers stdstring


【解决方案1】:

最好的解决方案是转储 C,使用 C++ 并摆脱一团糟。但由于您可能无法做到这一点,下一个最佳解决方案是创建您自己的 C 可见结构和一些 C 可见函数(本质上是 PIMPL),在 C++ 源代码中定义它们(这样您就可以从 std::string 中受益)并使用它们C. 像这样的东西。

strUtils.h 标头中:

#ifdef __cplusplus
extern "C" {
#endif
typedef struct cpp_string cpp_string;

cpp_string *cpp_string_create(const char *txt, int size);
void cpp_string_free(cpp_string *);
cpp_string *cpp_string_add(cpp_string *, cpp_string *);
... // all operations you need

#ifdef __cplusplus
}
#endif

在 C++ 源代码中 (strUtils.cpp):

#include <string>
struct cpp_string {
  std::string str;
  cpp_string(std::string str): str(std::move(str)) { }
};
extern "C" cpp_string *cpp_string_create(const char *txt, int size)
{
  return new cpp_string{ std::string{ txt, (size_t)size } };
}

// fill operations here
// since this is C++ file, just use std::string without copying

现在,当你想使用它时,你可以这样做:

int main()
{
    cpp_string *s = cpp_string_create("qwerty", 6);
    // do something with s

    // dont forget to free s
    cpp_string_free(s);

    return 0;
}

这通过创建自己的数据来回避整个 can-i-overwrite-someone-elses-memory(不,你不能,除非你想遇到奇怪、奇怪的问题)。

【讨论】:

  • 与我尝试的所有其他方法相比,这种方法对我来说是最好的。如果我仔细编程,只会制作一份。非常感谢@Radoslaw
猜你喜欢
  • 1970-01-01
  • 2015-05-19
  • 2010-12-12
  • 1970-01-01
  • 2020-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多