這可能是一個非常基本的 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 指標指向一個不再存在的變數,即使它仍然存在,結構的每個部分都會指向同一個變數,而不是它應該是的內容。
我知道這是一個相當基本的問題,但我現在已經不知道要搜索什么了,所以歡迎大家提供幫助。
uj5u.com熱心網友回復:
如果您想以只要結構處于活動狀態就保留的方式存盤字串資料,那么std::string就這樣做。因此,理想情況下,你應該更換const char*的成員connection_details有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.
}
然后,你可以.c_str()在任何你會使用的地方使用const char*
// 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;
// ...
}
uj5u.com熱心網友回復:
除了@Frank 對std::string用法的回答之外,如果由于某種原因您不能在結構內部使用 std::string,那么您應該手動執行低級 C 字串操作。
使用strdup()函式分配 復制一個字串。只需將= str.c_str()您的代碼更改為= strdup(str.c_str()),就是這樣,作業解決方案!
不要忘記在程式的最后釋放所有這些分配的指標,或者如果您決定將其他值串入該指標,以避免記憶體泄漏(如果您對某些泄漏不滿意,那么您可以決定不使用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();
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/366066.html
