TStringList

En Delphi cuentas con una clase muy utilizada llamada TStringList, en C++ Builder también existe esta clase. Esta clase trabaja como si fuera un array de strings, permitiendo mover Items, añadir, borrar e incluso cargarlos y guardarlos desde un fichero de texto plano.

En el GNU C Compiler no existe nada parecido a esto, así que en una tarde de aburrimiento se me ocurrió crear una pequeña clase en C++ que emule las funciones de la clase TStringList de Delphi.

El header de la clase es este:

#ifndef _H_STRINGLIST
#define _H_STRINGLIST

/*
 * File: stringlist.h
 * Este archivo contiene la definición de la clase TStringList
 * Desarrollado por Khronos
 *
 * email: khronos14@hotmail.com
 * blog: khronos14.blogspot.com
*/

struct SL_ITEM{
    char *string;
};

class TStringList{
    private:
        SL_ITEM *Items;
        long numItems;
    public:
        TStringList();
        ~TStringList();
        void Add(char *string);
        long GetCount();
        char * GetItem(long Index);
        bool InsertItem(long Index, char *string);
        bool DeleteItem(long Index);
        bool SetItem(long Index, char *string);
        bool SaveToFile(char * FileName);
        bool LoadFromFile(char * FileName);
};

#endif


El archivo cpp:
/*
 * File: stringlist.cpp
 * Este archivo contiene la implementación de los métodos
 * de la clase TStringList.
 * Desarrollado por Khronos
 *
 * email: khronos14@hotmail.com
 * blog: khronos14.blogspot.com
*/

#include "stringlist.h"
#include "string.h"
#include "fstream"

/*
 * Las cabeceras string.h y fstream las pongo entre comillas dobles
 * por el sistema de resalto de código del blog :S 
*/

using namespace std;

TStringList::TStringList()
{
    numItems = 0;
}

TStringList::~TStringList()
{
    if (numItems > 0)
        delete [] Items;
}

void TStringList::Add(char *string)
{
    if (numItems > 0){
        SL_ITEM * NewItems = new SL_ITEM[numItems + 1];
        for (int i = 0; i < numItems; i++)
            {
                NewItems[i].string = new char[strlen(Items[i].string) + 1];
                strcpy(NewItems[i].string, Items[i].string);
            }
        delete [] Items;
        Items = NewItems;
    }
    else Items = new SL_ITEM[1];
        Items[numItems].string = new char[strlen(string) + 1];
        strcpy(Items[numItems].string, string);
        numItems++;
}

bool TStringList::InsertItem(long Index, char *string)
{
    if (Index >= 0 && Index < numItems)
    {
        SL_ITEM * NewItems = new SL_ITEM[numItems + 1];
  int u = 0;
        for (int i = 0; i < numItems; i++)
        {
            if (Index == i)
            {
                NewItems[u].string = new char[strlen(string) + 1];
                strcpy(NewItems[u].string, string);
                u++;
            }
            NewItems[u].string = new char[strlen(Items[i].string) + 1];
            strcpy(NewItems[u].string, Items[i].string);
            u++;
        }
        delete [] Items;
        Items = NewItems;
        numItems++;
    }
    else return false;
}

bool TStringList::DeleteItem(long Index)
{
    if (Index >= 0 && Index < numItems)
    {
        SL_ITEM * NewItems = new SL_ITEM[numItems - 1];
  int u = 0;
        for (int i = 0; i < numItems; i++)
  {
            if (i != Index)
            {
                NewItems[u].string = new char[strlen(Items[i].string) + 1];
                strcpy(NewItems[u].string, Items[i].string);
                u++;
            }
  }

        delete [] Items;
        Items = NewItems;
        numItems--;
        return true;
    }
    else return false;
}

long TStringList::GetCount()
{
    return numItems;
}

char * TStringList::GetItem(long Index)
{
    if (Index < numItems && Index >= 0)
        return Items[Index].string;
    else return NULL;
}

bool TStringList::SetItem(long Index, char *string)
{
    if (Index >= 0 && Index < numItems)
    {
        delete [] Items[Index].string;
        Items[Index].string = new char[strlen(string) + 1];
        strcpy(Items[Index].string, string);
        return true;
    }
    else return false;
}

bool TStringList::SaveToFile(char * FileName)
{
char separator[] = "\r\n";
char *Buff;

    ofstream stream(FileName, ofstream::binary);
    if (stream != NULL)
    {
        for (int i = 0; i < GetCount(); i++)
        {
            Buff = GetItem(i);
            if (Buff != NULL)
            {
                stream.write(Buff, strlen(Buff));
                if (i != GetCount() - 1)
                    stream.write(separator, 2);
            }
         }
         stream.close();
         return true;
    }
    return false;
}

bool TStringList::LoadFromFile(char * FileName)
{
char *buff;
string line;
    ifstream stream(FileName, ifstream::binary);
    if (stream != NULL)
    {
        while (stream.good())
        {
            getline(stream, line);
            buff = new char[line.length() + 1];
            strcpy(buff, line.c_str());
            Add(buff);
            delete [] buff;
        }
        stream.close();
        return true;
    }
    return false;
}

Se podría hacer un sencillo ejemplo con esta clase:
#include "iostream"
#include "stringlist.h"

using namespace std;

int main(int argc, char* argv[])
{
    TStringList *List = new TStringList();

    List->LoadFromFile("datos.txt");
    if (List->GetCount() > 0)
    {
        cout << "Se cargaron " << List->GetCount() 
        << " Items en el TStringList" << endl;
        for (int i = 0; i < List->GetCount(); i++)
            cout << "Item numero " << i
            << " = " << List->GetItem(i) << endl;
    }
    else {
        cout << "El TStringList esta vacio..." << endl;
        cout << "Vamos a introducir algo..." << endl;
        List->Add("Cadena 1");
        List->Add("Esto es una prueba");
        List->Add("TStringList class...");
        List->InsertItem(2, "Cadena insertada en la posicion 2");
        List->SaveToFile("datos.txt");
    }
    delete(List);
}

Código fuente: http://www.megaupload.com/?d=4T89LLOE

Para compilar el programa:
g++ main.cpp stringlist.cpp -o stringlist

0 Response to "TStringList"

Publicar un comentario