【问题标题】:Function to concat two char* in C++在 C++ 中连接两个 char* 的函数
【发布时间】:2011-12-13 18:24:46
【问题描述】:

首先,我是一名 C# 程序员,所以我对 C++ 的工作知识相当有限。大学的时候拿回来的,10年没碰过,如果是比较简单的东西请见谅。

我正在尝试制作一个可以在 C# 中使用的 DLL,它实现了 libwpd 库。

我已经成功创建了一个 DLL,它导出了我可以通过 P/Invoke 访问的 2 个函数。第一个返回一个常量整数(由 Visual Studio 作为示例生成),第二个返回一个字符串。

如果我从函数返回一个常量字符串,它会成功传递给 C#,我可以在另一端读取它,所以我知道数据正在被传回。

我遇到的问题是 libwpd。我不得不修改他们的 TextDocumentGenerator.cpp 文件以将信息添加到 char* 而不是使用他们使用的 printf 以便我以后可以访问它。

我已将变量定义添加到头文件的公共部分,以便我可以从调用代码中读取它。

现在,我正在尝试编写一个函数,允许我将 libwpd 提供的 char* 添加到外部 char*。

我想出了这个:

char* addString(const char* addThis, char* toThis)
{
char* copier  = (char*)malloc(strlen(toThis) + 1 + 1);
strcpy(copier, toThis);
strcpy(copier, "1");

toThis = (char*)malloc(strlen(copier) + 1);
strcpy(toThis, copier);

return copier;
} 

但是当我传回信息时,我得到一个空白字符串。

我通过调用totalFile = addString("\n", totalFile);来调用函数

(我意识到它应该只在技术上重复添加“1”到字符串中,但它甚至没有这样做)

如果我将复印机线路的 strcpy 更改为 strcat,它会锁定。

我不知道如何在 C++ 中创建程序,所以我什至可以通过这些函数来查看发生了什么。

我们将不胜感激。

【问题讨论】:

  • strcpy(copier, toThis); strcpy(copier, "1"); - 一方面,第二个strcpy 会覆盖第一个的结果。
  • 如果你发现自己在 C++ 中使用malloc,这几乎总是意味着你做错了什么。如果你发现自己在 C++ 中使用new,这可能仍然意味着你做错了什么;标准模板库中已经提供了许多需要new 的常见场景。
  • @Trevor 一个友好的提示:我建议将您的 C++ 项目编译为 C++/CLI,并在项目中为本机代码创建一个托管包装器。这样,它与它的接口就更干净了。您只需像往常一样添加一个引用,就可以创建包装器的托管实例,其中包含指向本机类的非托管指针。
  • 不要忘记在 DLL 中编写和导出另一个函数来释放分配的字符串。 DLL 有它自己的内存管理器。

标签: c++ visual-studio-2008 dll strcat


【解决方案1】:

你知道std::string的存在吗?它是一个在 C++ 中处理字符串的类; char * 是 C 的遗产。

std::string 提供+ 运算符,可以满足您的需求。

【讨论】:

  • 我不知道 std::string。我必须使用的现有代码和我的学校使用 char*,所以这就是我试图使用的。我似乎无法访问 std::string (缺少包含?)但会寻找它。
  • 他想从c#调用这个,所以std::string是行不通的(至少对于参数和返回值)。
  • #include 。下次,谷歌搜索“cppreference ”来获取此类信息;)
  • @crashmstr,你知道有两种方法可以从字符串中获取char *吗? c_str()&str[0]?
  • 废话。显然使用 #include 与 libwpd 中现有的所需流类冲突。 C让我的眼睛流血。感谢您的所有帮助。不知道我要去哪里。
【解决方案2】:

您需要为返回字符串分配足够的空间,将初始字符串复制到目标缓冲区,然后调用 strcat 附加额外的信息。

例如:

char* addString(const char* addThis, const char* toThis)
{
    char* destination = (char*)malloc( strlen( addThis ) + strlen( toThis ) + 1 );
    strcpy( destination, toThis );
    strcat( destination, addThis );
    return destination;
} 

别忘了在调用此函数后的某个时间点您需要调用free( destination )

编辑: 当然,这只是我修复您问题中提出的功能。实际上,从函数返回指针并指望调用者释放它并不是一个好主意。由于您使用的是 C++ 而不是 C,因此使用一些 C++ 结构(例如 std::string 或至少将 char* 包装在 shared_ptr 或类似结构中)可能会好得多。

如果您要编写 C++,我建议您购买自己的 a good book 在这个主题上,如果您不知道自己在做什么,那真的太容易自取其辱了。

【讨论】:

  • 这不一定是个好主意。您已经让调用者负责释放您分配的内存块。这和不使用shared_ptr 一样糟糕。您正在分配内存,然后说“该死的”。有些人可能不同意,但我认为这是不好的做法。
  • @Moo-Juice 我同意,我个人永远不会编写这样的函数。我只是在修复问题中提出的函数的混乱。我想可能会在免责声明中进行编辑。
  • 第一个的 strcmp 是我更改它时导致它锁定的原因。以 strcpy/strcmp 的方式执行它让它运行超过这一点。如果我能克服链接错误,我可能会研究 sprintf 或 std::string 。感谢 cmets!
【解决方案3】:

由于您要替换 printf() 调用,sprintf() 可能是创建字符串的最简单方法。

【讨论】:

  • 这看起来相对有希望,直到所需的包含破坏了 libwpd。感谢您的评论!
  • @Trevor:它应该只需要 printf 也需要的相同包含,<stdio.h> 标头。
【解决方案4】:

首先,Griwes 是正确的。你没有做你正在做的事情并将这个问题标记为 C++。原因很简单,这不是我们在 C++ 中处理字符串的方式。

由于您是 C# 程序员,因此您非常了解 String 类。嗯,std::string 是类似的。它消除了处理琴弦的麻烦,因此您不必走上痛苦的路线。

在 C++ 中将两个字符串连接在一起,很简单:

std::string a = "I slept with ";
std::string b = "a heavy heart.";
std::string c = a + b;

瞧。

【讨论】:

  • 这样做的缺点是使用遗留代码或最初用 char* 编写的代码。您可以从 std::string 转换为 char* 并再次返回而不会出现问题吗?我也无权访问 std::string (在某处缺少包含)。在学校和我正在修改的现有源代码中,使用了 char*,所以我使用了 char*。如果我可以访问它,我肯定会研究 std::string。
  • @TrevorWatson,是的。在上面的例子中,调用c.c_str() 会给你一个普通的const char*
  • @TrevorWatson:std::string 是标准模板库的一部分。它将包含在任何体面的 C++ 编译器中。使用char * 代替std::string 类似于在C# 中使用char[] 而不是使用System.String
猜你喜欢
  • 1970-01-01
  • 2016-09-07
  • 2014-12-20
  • 2015-04-06
  • 2013-08-30
  • 2011-01-14
  • 2014-08-06
  • 1970-01-01
相关资源
最近更新 更多