[C con Clase] Duda sobre crear y usar banderas y alternativas a system()

Antonio Arjona antonio.arjona.melches en gmail.com
Mar Mayo 21 01:35:33 CEST 2013


Hola a todos.

Mi principal duda es la siguiente:
     A falta de conocer alguna biblioteca dedicada a esto, estoy creando 
una clase que me permita navegar entre directorios, y el caso es que 
para las opciones de configuración me gustaria utilizar banderas pero no 
tengo muy claro como funcionan los operadores de bits...
Estoy aprendiendo por mi cuenta, por tanto perdonadme si meto tanto 
código, si alguien desea ver todo el código tan solo pedírmelo y lo subo 
a github.com, muchas gracias de antemano...

De momento lo que tengo es lo siguiente:

// tengo declaradas unas pocas constantes

#define MOSTRAR_OCULTOS     0
#define INVERTIR_ORDEN         1
#define ORDENA_TAMAÑO        2
#define ORDENA_EXTENSION   3
//__etc.__

// y dentro de mi clase he creado un struct tal que asi:

struct conf
         { /**< ls = comando de consola Linux (muestra contenido 
directorio) */
bool archOcultos; /**< ls -all muestra todos los archivos, incluidos los 
ocultos */
bool invertir; /**< ls -r ordena el resultado en orden inverso */
bool tamano; /**< ls -S ordena el resultado por tamaño */
bool extension; /**< ls -X ordena por extension */
// etc.

void cambia(int opcion);   /
         }conf;


void FileManager::conf::cambia(int opcion)
{
if (opcion = MOSTRAR_OCULTOS)
         {
if ( archOcultos == false) archOcultos = true;
else archOcultos = false;

         }
// etc.
}

Tras investigar por mi cuenta, mas o menos creo que seria tal que así:

// los #defines de las banderas

#define MOSTRAR_OCULTOS     0x00000001
#define INVERTIR_ORDEN         0x00000010
#define ORDENA_TAMAÑO        0x00000100
#define ORDENA_EXTENSION   0x00001000
// etc.

// y pretendo usar las banderas miclase::conf::cambia(MOSTRAR_OCULTOS | 
INVERTIR_ORDEN |  etc...)

void FileManager::conf::cambia(Uint32 opcion)
{
// mostrar archivos ocultos
if ((opcion >> 0) &0xf  == 0x1)
         {
if ( archOcultos == false) archOcultos = true;
else archOcultos = false;

         }

// invertir el orden de aparición
if ((opcion >> 4) &0xf == 0x1)
         {
if ( invertir == false) invertir = true;
else invertir = false;

         }
// etc.
}

Esto seria correcto?
...............................

La otra cuestión es la manera que estoy usando para desplazarme entre 
directorios, aunque me funciona perfectamente con Linux, quisiera saber 
si es una manera correcta de hacer esto y si hay alternativas mejores, 
mi intención es que en un futuro sea multi plataforma.
Lo que hago es:

Capturar en un string el directorio de trabajo actual desde el 
constructor de la case

     actual_Dir = getenv("PWD");

Y para capturar el contenido utilizo system() redireccionando la salida 
del comando a un archivo de texto, lo cual no me parece que sea lo mas 
adecuado y donde surge mi duda de si existe alguna forma mejor de hacer 
esto, ademas de que todo cambiaría según el S.O. ...

string TmpTXT;
/**< NOTA faltan las opciones de configuración que irían justo después 
de la conf mínima para ls */
     TmpTXT = "ls --group-directories-first -p \"" /* conf mínima para 
ls (mostrar primero los directoriod, y marcarlos añadiendo un slash '/' ) */
+ actual_Dir +"\" > .tmp/.dirdat.dat";

if (system(TmpTXT.c_str()) !=0)
     {
         system("mkdir .tmp");
         system(TmpTXT.c_str());
     }

De forma que solo tengo que leer el archivo .tmp/.dirdat.dat para 
extraer el numero de datos (archivos y directorios) y sus nombres. 
capturandolos en un struct creado dinámicamente, aunque estoy creando 
una lista dinámica sencillita...

struct _dato_
         {
std::string dato;/**< nombre del archivo o directorio */
bool tipodato;/**< si es un directorio = false, si es true es un archivo 
de cualquier tipo */
void load(std::string Dato);
         } *dato;

Para moverme por los distintos directorios tan solo modifico el string 
"actual_Dir" eliminando a partir del ultimo separador de directorio, o 
añadiendo el string perteneciente al directorio al que quiera descender..

    void FileManager::SubirNivel()
    {

         actual_Dir.resize (actual_Dir.find_last_of("/"));  /**< de esta
    forma elimino el ultimo slash, y lo que valla a continuación
    subiendo un nivel */

         cargar_directorio(); /**< elimina si existe el array de struct
    _dato_, y crea uno nuevo con la info */

    }

    void FileManager::BajarNivel(int Ndato)
    {
    if (dato[Ndato].tipodato == false) /**< compruebo que sea un
    directorio */
         actual_Dir = actual_Dir+"/"+dato[Ndato].dato;/**< añado un
    slash, y el nombre del directorio deseado */
         cargar_directorio();
    }


------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://listas.conclase.net/pipermail/cconclase_listas.conclase.net/attachments/20130521/c790d719/attachment.html>


Más información sobre la lista de distribución Cconclase