Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

save line from file to char pointer in c++, without pointing to variable

This might be a very basic c/c++ question, but I am really struggeling at it right now.

I have a struct that looks something like this:

struct connection_details {
    const char *server, *user, *password, *database, *mysql_port, *ssh_port;
};

And I have the data in a seperate text file.
So I would like to write a function, that takes a pointer to the struct, to write each line of the text file to the corresponding variable of the struct.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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();
}

But now the char pointer points to a variable that no longer exists, and even if it still existed, every part of the struct would point to the same variabe, not the content it was supposed to be.

I know this is a rather basic question, but I came to the point where I don’t now what to google anymore, so every help is welcome.

>Solution :

If you want to store string data in a way that is kept around as long as the struct is alive, then std::string does exactly that. So, ideally, you should replace the const char* members of connection_details with std::string:

struct connection_details {
    std::string server, user, password, database, mysql_port, ssh_port;
}; 

Conveniently, this also allows you to just getline() directly into the members:

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.
}

Then, you can use .c_str() wherever you would have used the 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());
}

Edit: Now, if you have no control over connection_details, then you can still use std::string, but you just have to add a layer of indirection:

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;

  // ...
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading