【问题标题】:How to store char* dynamicly in a C++ loop? [closed]如何在 C++ 循环中动态存储 char*? [关闭]
【发布时间】:2021-12-31 08:02:19
【问题描述】:

Reposted here

我遇到了在程序中将任意地址注册为char* 的场景。为了简化问题,假设在将单词与句子分离后,我需要将每个单词作为char* 传递给 dll 库以进行进一步操作。 分析“Hello World”的静态方法如下:

...
#include third_party_lib;

char* w1 = "Hello".c_str();
char* w2 = "World".c_str();

third_party_function(w1);
third_party_function(w2);

显然w1w2 的命名是静态的,这意味着我必须手动编写它们的名称。不适合将任意数量的char* 变量传递给third_party_function。

我听说不能使用通配符命名变量,例如w_n,另一种方法是使用char* 的向量或数组。

我想出了这个:

#include<iostream>
#include<vector>
#include<cstring>
using namespace std;

int main()
{
  char* w[100];
  string a = "Hello";

  a.copy(w[0], a.size(), 0);
  cout << "w[0]: "<<w[0] <<endl;
  //third_party_function(w[0]);

  a = "World";
  cout << "a after: " <<a <<endl;

  a.copy(w[1], a.size(), 0);
  cout << "w[1]: "<< w[1] <<endl;
  //third_party_function(w[1]);
}

注意我重新使用了变量a,因为如果在循环中就会出现这种情况。 但是,第三个输出不是应该的,打印输出只有两行:

w[0]: Hello
a after: World

当然,这是两次失败的尝试。但是如何通过第三方库将任意数量的char* 变量传递给函数呢?

【问题讨论】:

  • ch[0] 是一个指针,但你永远不会让它指向任何地方。因此使用无效。
  • 而不是 char* ch[100] 为什么没有 std::string 的向量?然后,您可以将 .data() 传递给您调用的 dll 函数。我看不到 char* ch[100] 有什么附加价值
  • @AndersK 这 3 行在 main 中不起作用:vector&lt;char*&gt; ch; string a = "Hello"; ch.push_back(a.data());
  • @GeorgeY 看来你有 XY 问题。此外,完全不清楚您到底想要什么以及为什么使用char*。其次,由于使用了未初始化的变量,您的程序具有未定义的行为。在编写任何类型的程序之前,您应该参考一些好书,而不是做任意事情并期望它会导致您想要的输出(尤其是在C++)。
  • @Someprogrammerdude:哎呀,对,对不起。

标签: c++ char


【解决方案1】:

使用stringvector 避免这些指针和数组大小问题。当您需要将char* 从字符串传递给外部函数时,可以使用字符串类的.c_str() 成员。 (如果你使用data(),显然你不能保证空终止)。

例子:

vector<string> words;

string a = "Hello";
words.push_back(a); // you could also just say, words.push_back("Hello")
cout << "words[0]: "<< words[0] <<endl;

a = "World";
words.push_back(a);
cout << "words[1]: << words[1] << endl;

然后使用您的 words 向量,您可以枚举它并获取每个 string 实例内部的 char*

for (const string& word : words)
{
    some_library_function(word.c_str());
}

现在,如果 some_library_function 需要 char* 而不是 const char*,这暗示它修改了字符串,您需要制作它的临时副本:

for (const string& word : words)
{
    const char* str = word.c_str();
    size_t len = word.size();
    vector<char> tmp(str, str+len+1); // +1 for null char

    some_library_function(tmp.data());
}

【讨论】:

  • 感谢您的明确回答 selbie。但据我所知,char* 是一个指针。并且它会将char*的多个指针写入枚举for (const string&amp; word : words)中的内存而不最终破坏它们吗?
  • write multiple pointers 是什么意思?
  • 我了解到您不能将word.c_str() 直接用作函数的输入。您需要先命名一个类型为char* 的变量,并为其分配word.c_str(),然后再将该变量用作函数中的参数。否则函数.c_str()的结果根本不存储,因此会导致错误。
  • 向我展示您的函数的声明,该声明希望将 char 指针传递给它并描述它的作用。
  • 头文件中的这一行:virtual void RegisterFront(char *pszFrontAddress) = 0;RegisterFront函数可以随时重复使用,每个注册一个服务器的IP地址。一旦当前离线,第三方库将重新连接到另一个 IP。
【解决方案2】:

你写的时候

a.copy(ch[0], a.size(), 0);//this is undefined behavior

您正在使用ch[0]。但由于ch未初始化,这将导致未定义的行为

未定义的行为意味着任何事情1都可能发生包括但不限于给出您预期输出的程序。但是永远不要依赖(或根据)具有未定义行为的程序的输出。

例如here 程序似乎没有崩溃,但here 它有时会崩溃,有时不会。所以不要依赖有UB的程序的输出。

如果你想要char*,你可以使用std::string::c_str

    std::string a("Hello");

    char * cstr = new char [a.length()+1];
    std::strcpy (cstr, a.c_str()); //uses std::string::c_str 
    
    // cstr now contains a c-string copy of a
    
    //dont forget to uses delete 
    delete[] cstr;

1有关未定义行为的更准确的技术定义,请参阅this,其中提到:对程序的行为没有限制 .

【讨论】:

  • 是的,这种方式失败了。您能否找到一种“在将单词与句子分开后将每个单词传递为char*”的方法?
  • @GeorgeY 如果您想要char*,可以使用std::string::c_str,如我编辑的答案末尾所示。看看吧。
猜你喜欢
  • 1970-01-01
  • 2017-02-01
  • 1970-01-01
  • 2018-09-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-01
  • 2015-07-14
相关资源
最近更新 更多