Poesía Binaria

Definir valores de variables desde una cadena de caracteres [C++11]


A veces, es muy útil poder definir variables de diversos tipos (int, string, double, bool, etc) o incluso inicializar clases todo desde un string. El objetivo es dar al usuario de nuestro programa más libertad aún y no combernos demasiado la cabeza transformando cada una de las variables. Por otro lado, no siempre podrán estar definidas todas, por lo que hacer una solución específica para cada cao es un poco largo.

En github he publicado un proyecto para eso mismo: optf. Con sólo un archivo de cabecera podemos construir, por ejemplo, un conector de base de datos de la siguiente manera:

1
2
3
4
5
6
7
 DatabaseConnectorSample mc("dbtype=postgresql",
  "username=root",
  "host=localhost",
  "pconnect=true",
  "any=ANY OBJECT",
  "password=mypass",
  "port=1234");

Como decía antes, lo mejor es que no tenemos por qué definirlo todo y no tenemos que ceñirnos en el orden, podemos pasar directamente líneas de un fichero de configuración o generar las cadenas de caracteres con la información que nos pasa el usuario sin preocuparnos del tipo de dato que tendrá el atributo de la clase al que asignaremos el valor y sin tener que reescribir demasiadas veces el nombre de la variable.

Copio y pego uno de los ejemplos del proyecto:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include "optf.hpp"
#include <string>
#include <iostream>

using namespace std;
// This class can have many options to initialize
class MyClass
{
  public:
  MyClass(string arg1, string arg2)
  {
  optfs o(optfs::bind(&MyClass::set_option, this), arg1, arg2);
  // optfs o(bind(&MyClass::set_option, this, placeholders::_1, placeholders::_2), arg1, arg2);
  }

  void print()
  {
     cout << "BOOLEAN = "<< boolean <<endl;
     cout << "NUMBER = "<< number << endl;
  }

  private:
  bool boolean;
  double number;
  // Private function
  void set_option(const string opt, const string &val)
  {
    // Lets put all settable stuff
    OPTF_DEFINE(boolean);
    OPTF_DEFINE(number, 1);
  }
};

int main()
{
  MyClass mc("boolean=yes", "number=123.45");
  mc.print();
  return 1;
}

Basta con esta línea

1
  optfs o(optfs::bind(&MyClass::set_option, this), arg1, arg2);

a la que le pasaremos todos los strings que queramos parsear. Nuestra clase tendrá que tener una función llamada set_option() (su nombre lo podemos cambiar). Esa función deberá asignar el valor que vemos en la cadena de caracteres a la variable correspondiente.
Ahora podríamos pensar que tendríamos que tendríamos que dar el nombre de la variable en formato string y hacer que corresponda con la variable homónima pero optf se encargará de eso, sólo tenemos que crear las variables como atributos de la clase.
Ahora la función set_option, tendrá esta forma:

1
2
3
4
5
6
  void set_option(const string opt, const string &val)
  {
    // Lets put all settable stuff
    OPTF_DEFINE(boolean);
    OPTF_DEFINE(number, 1);
  }

Esta función recibirá el nombre de la opción que se define y el string con el valor, pero dentro de la función podremos llamar a OPTF_DEFINE(variable) y ya se encargará de todo. Cuando llamamos a OPTF_DEFINE(variable, 1) lo hacemos para poder un else delante de la condición (OPTF_DEFINE es una macro que ya se encarga de hacer el trabajo sucio).

Bueno, os invito a visitar el proyecto.

También podría interesarte....