这可能是一个非常基本的c/c++问题,但我现在真的很难回答。
我有一个结构,看起来像这样:
struct connection_details {
const char *server, *user, *password, *database, *mysql_port, *ssh_port;
};
我有一个单独的文本文件中的数据。因此,我想写一个函数,它取一个指向结构的指针,将文本文件的每一行写入结构的相应变量。
void get_config(const std::string &config_path, connection_details *mysql) {
ifstream file(config_path);
string str;
getline(file, str);
mysql->user = str.c_str();
getline(file, str);
mysql->server = str.c_str();
getline(file, str);
mysql->database = str.c_str();
//...
file.close();
}
但现在char指针指向一个不再存在的变量,即使它仍然存在,结构的每个部分都会指向同一个变量,而不是它应该指向的内容。
我知道这是一个相当基本的问题,但我现在不知道该用谷歌搜索什么了,所以欢迎一切帮助。
如果您希望以一种只要结构处于活动状态就可以保持的方式存储字符串数据,那么std::string
正是这样做的。因此,理想情况下,应该将connection_details
的const char*
成员替换为std::string
:
struct connection_details {
std::string server, user, password, database, mysql_port, ssh_port;
};
方便的是,这也允许您仅getline()
直接进入成员:
void get_config(const std::string &config_path, connection_details *mysql) {
ifstream file(config_path);
getline(file, mysql->user);
getline(file, mysql->server);
getline(file, mysql->database);
// ...
// No need to .close(), it's implicit.
}
然后,您可以在任何使用const char*
的地方使用.c_str()
// Assuming you can't change this...
void some_function(const char* str);
int main() {
connection_details details;
get_config("path/to_config.txt", &details);
// before:
//some_function(details.server);
// after:
some_function(details.server.c_str());
}
编辑:现在,如果你不能控制connection_details
,那么你仍然可以使用std::string
,但你只需要添加一层间接:
struct connection_details {
const char* server, user, password, database, mysql_port, ssh_port;
};
struct connection_details_data {
std::string server, user, password, database, mysql_port, ssh_port;
// Make it convertible into connection_details
operator connection_details() const {
return {
server.c_str(), user.c_str(), password.c_str(),
database.c_str(), mysql_port.c_str(), ssh_port.c_str()
};
}
};
void get_config(const std::string &config_path, connection_details *mysql) {
// ...
}
int main() {
connection_details_data details_data;
get_config("path/to_config.txt", &details_data);
// Make sure details_data outlives details!
connection_details details = details_data;
// ...
}
除了@Frank关于std::string
用法的回答之外,如果由于某种原因不能在结构中使用std::string,那么您应该手动执行低级C字符串操作。
使用strdup((函数来分配+复制字符串。只需将代码中的= str.c_str()
更改为= strdup(str.c_str())
,即可实现工作解决方案!
不要忘记在程序的最后释放((所有这些分配的指针,或者如果你决定将其他值strdup到这些指针中,以避免内存泄漏(如果你对一些泄漏不满意,那么你可能会决定不使用free()
(。
#include <cstring>
void get_config(const std::string &config_path, connection_details *mysql) {
ifstream file(config_path);
string str;
getline(file, str);
mysql->user = strdup(str.c_str());
getline(file, str);
mysql->server = strdup(str.c_str());
getline(file, str);
mysql->database = strdup(str.c_str());
//...
file.close();
}