如何在 C++ 中动态分配 char* 变量?
How to assign char* variables dynamicly in C++?
我遇到了在program.I中将任意地址注册为char*
的场景,需要将每个地址作为char*
传递给第三方库以进行进一步操作。
third_party_function 在其头文件中是这样描述的:
virtual void RegisterFront(char *pszFrontAddress) = 0;
首先,程序必须从配置文件中读取一组地址,例如:
tcp://18.19.20.22:7778; tcp://18.19.20.24:7778; tcp://18.19.20.25:7778;
如果我将其定义为 cstring 并使用循环,则分析该字符串并将其分解为地址向量的过程很简单。但是每个都必须在该函数中注册,以便库在当前失败时连接到另一个地址。当前配置有 3 个地址,但应该允许任意数量的地址。
分配 char*
变量的静态方法是这样的:
...
#include third_party_lib;
char* addr1 = "tcp://18.19.20.22:7778".c_str();
char* addr2 = "tcp://18.19.20.24:7778".c_str();
RegisterFront(addr1);
RegisterFront(addr2);
我省略了从配置中分析地址的循环,但本质很清楚:我不能在程序中命名 addr[n],因为地址的数量是不确定的——这取决于有多少会写在该配置行中。
即对于 3 地址场景,我可以在代码中分配 addr1
addr2
addr3
。但是一旦编译完成,如果配置行现在只包含两个地址怎么办?改成 5 怎么样?
- 如何改进上述实现动态分配任意数量的
char*
变量并将它们中的每一个传递给第三方函数RegisterFront
? - 当然你可以换成一些打印功能试试,但是输入类型要一样。
顺便说一句:RegisterFront
函数的替换:
void printFront(char *addr){
cout << addr <<endl;
}
假设您的配置行是这样的:
std::string s = "tcp://18.19.20.22:7778; tcp://18.19.20.24:7778; tcp://18.19.20.25:7778;"
s
也可以是一个char*,没关系。在您的代码中的某个时刻,您已经获得了您从文件或任何地方读取的配置行的字符串表示形式。
然后为每个 URL 遍历该字符串,所有 RegisterFront
函数就是这个。
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
void trim(std::string& s) {
size_t start = 0;
size_t end = s.size();
while ((start < end) && isspace(s[start]))
{
start++;
}
while ((end > start) && isspace(s[end - 1]))
{
end--;
}
s = s.substr(start, end - start);
}
void RegisterAddresses(const std::string& config_line) {
std::istringstream ss(config_line);
std::string address;
while (std::getline(ss, address, ';')) {
trim(address);
// address[0] returns a reference to the first char in the string
// hence, &address[0] is the char* to the front of the string
RegisterFront(&address[0]);
}
}
然后当您拥有 config_line(定义为 char*
或 std::string
实例)时,您只需以任一方式调用它:
std::string s = "tcp://18.19.20.22:7778; tcp://18.19.20.24:7778; tcp://18.19.20.25:7778;";
RegisterAddresses(s);
这也有效(临时 std::string 传递给 RegisterAddresses - 从传入的 char* 构造)
const char* s = "tcp://18.19.20.22:7778; tcp://18.19.20.24:7778; tcp://18.19.20.25:7778;";
RegisterAddresses(s);
我遇到了在program.I中将任意地址注册为char*
的场景,需要将每个地址作为char*
传递给第三方库以进行进一步操作。
third_party_function 在其头文件中是这样描述的:
virtual void RegisterFront(char *pszFrontAddress) = 0;
首先,程序必须从配置文件中读取一组地址,例如:
tcp://18.19.20.22:7778; tcp://18.19.20.24:7778; tcp://18.19.20.25:7778;
如果我将其定义为 cstring 并使用循环,则分析该字符串并将其分解为地址向量的过程很简单。但是每个都必须在该函数中注册,以便库在当前失败时连接到另一个地址。当前配置有 3 个地址,但应该允许任意数量的地址。
分配 char*
变量的静态方法是这样的:
...
#include third_party_lib;
char* addr1 = "tcp://18.19.20.22:7778".c_str();
char* addr2 = "tcp://18.19.20.24:7778".c_str();
RegisterFront(addr1);
RegisterFront(addr2);
我省略了从配置中分析地址的循环,但本质很清楚:我不能在程序中命名 addr[n],因为地址的数量是不确定的——这取决于有多少会写在该配置行中。
即对于 3 地址场景,我可以在代码中分配 addr1
addr2
addr3
。但是一旦编译完成,如果配置行现在只包含两个地址怎么办?改成 5 怎么样?
- 如何改进上述实现动态分配任意数量的
char*
变量并将它们中的每一个传递给第三方函数RegisterFront
? - 当然你可以换成一些打印功能试试,但是输入类型要一样。
顺便说一句:RegisterFront
函数的替换:
void printFront(char *addr){
cout << addr <<endl;
}
假设您的配置行是这样的:
std::string s = "tcp://18.19.20.22:7778; tcp://18.19.20.24:7778; tcp://18.19.20.25:7778;"
s
也可以是一个char*,没关系。在您的代码中的某个时刻,您已经获得了您从文件或任何地方读取的配置行的字符串表示形式。
然后为每个 URL 遍历该字符串,所有 RegisterFront
函数就是这个。
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
void trim(std::string& s) {
size_t start = 0;
size_t end = s.size();
while ((start < end) && isspace(s[start]))
{
start++;
}
while ((end > start) && isspace(s[end - 1]))
{
end--;
}
s = s.substr(start, end - start);
}
void RegisterAddresses(const std::string& config_line) {
std::istringstream ss(config_line);
std::string address;
while (std::getline(ss, address, ';')) {
trim(address);
// address[0] returns a reference to the first char in the string
// hence, &address[0] is the char* to the front of the string
RegisterFront(&address[0]);
}
}
然后当您拥有 config_line(定义为 char*
或 std::string
实例)时,您只需以任一方式调用它:
std::string s = "tcp://18.19.20.22:7778; tcp://18.19.20.24:7778; tcp://18.19.20.25:7778;";
RegisterAddresses(s);
这也有效(临时 std::string 传递给 RegisterAddresses - 从传入的 char* 构造)
const char* s = "tcp://18.19.20.22:7778; tcp://18.19.20.24:7778; tcp://18.19.20.25:7778;";
RegisterAddresses(s);