将文件中的行保存到 C++ 中的 char 指针,而不指向变量
save line from file to char pointer in c++, without pointing to variable
这可能是一个非常基础的 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指针指向一个不再存在的变量,即使它仍然存在,结构的每一部分都会指向同一个变量,而不是它应该是的内容。
我知道这是一个相当基本的问题,但我已经到了现在不知道要做什么的地步 google,所以欢迎大家提供帮助。
如果您想以一种只要结构还活着就一直存在的方式来存储字符串数据,那么 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())
即可,有效的解决方案!
不要忘记在程序的最后 free() 所有这些分配的指针,或者如果您决定将其他值添加到该指针中,以避免内存泄漏(如果您不满意一些泄漏,那么你可能决定不使用 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();
}
这可能是一个非常基础的 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指针指向一个不再存在的变量,即使它仍然存在,结构的每一部分都会指向同一个变量,而不是它应该是的内容。
我知道这是一个相当基本的问题,但我已经到了现在不知道要做什么的地步 google,所以欢迎大家提供帮助。
如果您想以一种只要结构还活着就一直存在的方式来存储字符串数据,那么 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())
即可,有效的解决方案!
不要忘记在程序的最后 free() 所有这些分配的指针,或者如果您决定将其他值添加到该指针中,以避免内存泄漏(如果您不满意一些泄漏,那么你可能决定不使用 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();
}