Imaginemos un mundo libre

La paz interior comienza en el momento en el que decides no permitir, que ninguna persona o evento, tome el control de tus emociones.

Manejo de Strings con Qt – QString , QChar, QStringList

with 3 comments

Trabajar con cadenas de caracteres (Strings), es algo que se realiza a menudo en la programación informática.

Qt nos proporciona la clase QString que nos va a permitir crear cadenas de tipo Unicode.

Unicode es un estándar internacional que actualmente usan la mayoría de sistemas de escritura y funciona básicamente asignando un código binario a cada caracter.

Lo que permite Unicode es que los usuarios puedan visualizar la información de los programas sin ningún problema, independientemente del idioma y de la plataforma sobre la cual está construido el software.

La clase QString permite manipular la información de estas cadenas tipo Unicode y además convertirlas a otros tipos de datos.

Cuando se crea una cadena en realidad lo que está pasando es que Qt almacena una cadena compuesta por un conjunto de QChars (caracteres) de 16 bits. Veremos la clase QChar más adelante.

Vamos a revisar paso a paso los métodos más importantes de QString.

Debemos incluir la clase por supuesto:

#include <QString>

¿Cómo definimos una cadena?
QString str(“Mi cadena”);

Si queremos añadir caracteres al inicio de una cadena:
str.prepend(“Texto al inicio “);

Añadir caracteres al final de una cadena:
str.append(” Texto al final”);

Para reemplazar una cadena por otra:
str.replace(10,4,”Nuevo texto”); // A partir del caracter 10, remover 4 caracteres y reemplazar por Nuevo Texto.

Para eliminar caracteres de una cadena:
str.remove(5,5) ; // A partir del caracter 5, remover 5 caracteres.

Para definir el tamaño exacto de una cadena:
str.resize(10); // Puede contener solo 10 caracteres.

Para retornar el tamaño de una cadena.
str.size();

Para retornar el número de caracteres de una cadena. (Similar a size)
str.length();

Para eliminar espacios en blanco al inicio y final de una cadena:
str.trimmed();

Para eliminar espacios en blanco del principio y del final y reemplazar un caracter considerado como espacio por un espacio en blanco.
str.simplified();

Para comprobar si una cadena es vacía:
str.isEmpty();

Para buscar un caracter en una posición determinada de una cadena:
str.indexOf(“caracter”,posicion);

Para retornar la posición de la última ocurrencia encontrada en una cadena:
str.lastIndexOf(“caracter”);

Para comprobar si existe una ocurrencia dentro de una cadena:
str.contains(“cadena”, Qt::CaseInsensitive); // Retorna True o False

// Qt::CaseInsensitive no diferencia mayúsculas de minúsculas y también existe Qt::CaseSensitive que produce el efecto contrario.

Para determinar si una cadena empieza con determinados caracteres:
str.startsWith(“car”); // Retorna True o False

Para determinar si una cadena finaliza con determinados caracteres:
str.endsWith(“car”); // Retorna True o False

Para limpiar el contenido de una cadena:
str.clear();

También podemos crear la cadena inicialmente vacía y después agregarle los caracteres con:
QString str;
str.setNum(15);

Para convertir una cadena a flotante:
int num = str.toDouble();

Para convertir una cadena a entero:
int num = str.toInt();

Si la cadena está formada por caracteres entonces, puedes transformar esa cadena a entero usando una base que puede estar entre 2 y 36. Por defecto es 10.

Por ejemplo si quiero transformar la cadena “FFF” del sistema hexadecimal a un entero uso la base 16, base usada por el sistema hexadecimal.

En este caso la función toInt() recibe 2 parámetros uno de tipo booleano que por defecto es True y la base a la que sea desea convertir.

QString str = “FFF”;
bool ok;
int num = str.toInt(&ok, 16);
// 4095 sería el valor de num

Si existe un error en la conversión, por ejemplo queremos convertir “loquesea” a entero, entonces ok devuelve False y el entero tendrá como valor 0.

Si la cadena empieza con “0x” se usa la base 16, si empieza con “0” se usa la base 8, de lo contrario se usa la base 10.

Para convertir un número a una cadena:
QString str = QString::number(9.0); // str sería igual a “9”

Y también podríamos hacer lo opuesto a lo que hicimos anteriormente, convertir un número a una cadena dependiendo de la base.
int num = 255;
QString str = QString::number(d, 16);

// El valor de str es FF por la conversión del número 255 a hexadecimal (16)

QString tambiém tiene 4 métodos que nos van a permitir retornar una cadena de tipo const char *:

str.toAscii(); retorna una cadena de 8 bits de codificación ASCII.

str.toLatin1(); retorna una cadena de 8 bits de codificación Latin-1 (ISO 8859-1).

str.toUtf8(); retorna una cadena de 8 bits de codificación UTF-8.

El uso de UTF-8 es importántísimo para la internacionalización, ya que es un estándar y un formato para codificar caracteres Unicode (Como explicamos anteriormente) utilizando bytes de 1 a 4 por carácter. UTF-8 nos va a permitir tener compatibilidad entre programas y soportar múltiples caracteres.

str.toLocal8Bit(); retorna una cadena de 8 bits usando el sistema de codificación local.

La clase QString tiene muchísimas más funcionalidades, miembros y métodos avanzados como pueden apreciar en la documentación oficial de QT.

QChar es una clase que nos permite definir caracteres Unicode de 16 bits.

QChar similar a QString provee funciones que permiten convertir de y hacia otro formato y también funciones que permiten comprobar si el caracter es de cierto tipo de dato o formato.

Todas estas funciones retornan True si el caracter es de cierto tipo de dato, de lo contrario retornan False.

isNull(): // Si es nulo.

isPrint(); // Si es cualquier tipo de carácter que se pueda imprimir.

isPunct(); // Si es cualquier símbolo de puntuación.

isMark(); // Si es una marca Unicode.

isLetter(); // Si es letra.

isNumber(); // Si es número.

isLetterOrNumber(); // Si es letra o número.

isDigit(); // Si es un dígito decimal.

isSymbol(); // Si es un símbolo.

Otras funciones importantes:

toUpper(); // Convierte un caracter a mayúscula.

toLower(); // Convierte un caracter a minúscula.

category(); // Retorna la categoría Unicode a la que pertenece el caracter.

Unicode(); // Retorna una referencia al valor numérico Unicode del QChar.

QStringList es una clase que nos permite crear listas de cadenas(strings).

QStringList es una subclase de QList que usa el mismo método de manejo de arrays que C++, es decir, implementa un array de punteros.

Esta clase permite un acceso rápido a los elementos de la lista por medio de índices y permite realizar la tareas comunes de inserción, eliminación, agrupación, ordenación y búsqueda de elementos.

Debemos incluir la clase:

#include <QStringList>

Para definir una lista de strings:
QStringList idiomas;
idiomas << “English” << “Spanish” << “French” << “German” << “Japanese” << “Chinese”;

Por medio de índices es que podemos acceder a los elementos de la lista y tenemos 2 opciones:

Usar el operador [], que permite acceder a los elementos y asignar, modificar valores a los mismos:
strList[indice];

Y para un acceso de solo lectura también se puede usar at():
strList.at(indice);

at() es más rápido que [] puesto que no realiza lo que Qt llama una “deep copy” que lo que hace es duplicar un objeto, en vez de eso realiza una “shallow copy” que es simplemente una referencia a un objeto.

Una “deep copy” consume mucho más memoria y CPU y por el contrario una “shallow copy” es mucho más rápida puesto que solo implica fijar un puntero.

Vamos a revisar los métodos más importantes de QStringList.

Para ordenar los elementos de la lista:
strList.sort();

Para eliminar elementos:

removeAt(indice); // Elimina el elemento del indice indicado.

removeFirst(); // Elimina el primer elemento de la lista

removeLast(); // Elimina el último elemento de la lista

removeOne(“cadena”); Elimina el primer elemento que contenga la cadena que se especifica.

removeAll(“cadena”); // Elimina todos los elementos que contengan la cadena que se especifica.

QStringList así como QString también tiene los métodos contains(), indexOf(), lastIndexOf(), append(), prepend(), insert(),replace(), isEmpty() que vimos anteriormente y tienen la misma funcionalidad y comportamiento.

Para juntar todos los elementos de una lista en una cadena:
QString str = strList.join(“,”); // En este caso separamos los elementos de la lista de cadenas con comas.

Para romper una cadena y convertirla en una lista de cadenas:
QStringList strList;
strList = str.split(“,”);
// Asumiento que str es una cadena que contiene elementos separados por comas.

Existe también el método filter() que retorna una lista de todas las cadenas que contienen una subcadena especificada.
QStringList strList2;
strList2 = strList.filter(“ish”);
// Según nuestra lista creada, strList2 contendría los elementos English y Spanish.

Para reemplazar una cadena dentro de otra, en una lisa de cadenas:
strList.replaceInStrings(“i”, “e”);
// Reemplaza todas las i por e en todos las cadenas de la lista.

Bueno y para terminar que mejor que un pedazo de código que permite comprobar todo lo descrito.

Estoy usando QDebug, una clase de Qt que nos sirve para depurar el programa. Comúnmente llamado el debugging.

Mejor dicho, para ir mostrando la salida que produce el código del programa.

Lo que retorna cada operación está con comentarios.

Enjoy:

#include <QtGui/QApplication>
#include <QString>
#include <QStringList>
#include <QDebug>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    /********* Funcionamiento de QString *********/
    QString str("soy usuario ");

    str.append("de KDE ");
    qDebug() << str; // "soy usuario de KDE "

    str.prepend("Desde hace 3 años, ");
    qDebug() << str; // "Desde hace 3 años, soy usuario de KDE "

    str.replace(13, 4, " meses");
    str.replace(37, 3, " OpenSuse");
    qDebug() << str; // "Desde hace 3  meses, soy usuario de OpenSuse "

    str.insert(46," y Digikam.");
    qDebug() << str; // "Desde hace 3  mesess, soy usuario de  OpenSuse y Digikam. "

    str.remove(0,21);
    qDebug() << str; // " soy usuario de  OpenSuse y Digikam. "

    str.resize(25);
    qDebug() << str; // " soy usuario de  OpenSuse"

    QString str2 = "   Espacios en blanco al inicio y fin   ";
    str2.trimmed();
    qDebug() << str2; // " Espacios en blanco al inicio y fin "

    QString str3 = "Open Source";
    int i = 0;

    while ((i = str3.indexOf("e", i)) != -1) {
        qDebug() << "La letra e se encuentra en la posicion " << i;
        ++i;
    }
    // La letra e se encuentra en la posicion  2
    // La letra e se encuentra en la posicion  10

    QString str4  = "Konsole";
    qDebug() << str4.lastIndexOf("o"); // 4

    QString str5 = "Software Libre";
    qDebug() << str5.isEmpty(); // false
    qDebug() << str5.contains("libre", Qt::CaseInsensitive); // true

    QString str6;
    int j = 9999999;
    str6.append(QString("%1").arg(j));
    qDebug() << str6; // "9999999"

    QString str7 = "Amarok";
    qDebug() << str7.startsWith("Ama"); // true
    qDebug() << str7.endsWith("rok"); // true

    str7.clear();
    qDebug() << str7; // "" cadena vacía

    QString str8;
    str8.setNum(15);
    qDebug() << str8; // "15"

    QString str10 = "2010.03";
    float a = str10.toFloat();
    qDebug() << a; // 2010.03

    QString str11 = "12345789";
    int b = str11.toInt();
    qDebug() << b; // 12345789

    QString str12 = "FFF";
    bool ok;
    int c = str12.toInt(&ok, 16);
    qDebug() << c; // 4095

    QString str13 = QString::number(9.0);
    qDebug() << str13; // "9"

    int d = 255;
    QString str14 = QString::number(d, 16);
    qDebug() << str14; // "ff"

    /********* Funcionamiento de QChar *********/

    QChar chr = 'R';
    qDebug() << chr.isNull(); // false
    qDebug() << chr.isPrint(); // true
    qDebug() << chr.isPunct(); // false
    qDebug() << chr.isMark(); // false
    qDebug() << chr.isLetter(); // true
    qDebug() << chr.isNumber(); // false
    qDebug() << chr.isLetterOrNumber(); // true
    qDebug() << chr.isDigit(); // false
    qDebug() << chr.isSymbol(); // false

    qDebug() << chr.toLower(); // retorna 'r'
    qDebug() << chr.toUpper(); // 'R' nuevamente

    qDebug() << chr.category(); // 15, categoria Unicode del caracter
    qDebug() << chr.unicode(); // 82, valor numérico Unicode del caracter

    /********* Funcionamiento de QStringList *********/

    QStringList idiomas;
    idiomas << "English" << "Spanish" << "French" << "German" << "Japanese" << "German" << "Chinese";

    if ( idiomas[1] == "Spanish" ) {
        qDebug() << "Si existe Spanish";
    } else {
        qDebug() << "No existe";
    }
    // Si existe Spanish

    for (int i = 0; i < idiomas.size(); ++i) {
        qDebug() << idiomas.at(i); //
    }
    // "English"
    // "Spanish"
    // "French"
    // "German"
    // "Japanese"
    // "German"
    // "Chinese"

    QString str15 = idiomas.join(",");
    qDebug() << str15; // "English,Spanish,French,German,Japanese,German,Chinese"

    QStringList strList;
    strList = str15.split(",");
    qDebug() << strList; // ("English", "Spanish", "French", "German", "Japanese", "German", "Chinese")

    QStringList strList2;
    strList2 = strList.filter("ish");
    qDebug() << strList2; // ("English", "Spanish")

    strList2.replaceInStrings("i","e");
    qDebug() << strList2; // ("Englesh", "Spanesh")

    idiomas.sort();
    qDebug() << idiomas; // ("Chinese", "English", "French", "German", "German", "Japanese", "Spanish")

    idiomas.removeAt(1);
    qDebug() << idiomas; // ("Chinese", "French", "German", "German", "Japanese", "Spanish")

    idiomas.removeFirst();
    qDebug() << idiomas; // ("French", "German", "German", "Japanese", "Spanish")

    idiomas.removeLast();
    qDebug() << idiomas; // ("French", "German", "German", "Japanese")

    idiomas.removeOne("French");
    qDebug() << idiomas; // ("German", "German", "Japanese")

    idiomas.removeAll("German");
    qDebug() << idiomas; // ("Japanese")

    return app.exec();
}

El siguiente post será acerca de QByteArray.

Written by Ronny Yabar

March 11, 2010 at 6:56 am

Posted in Qt

Tagged with , , ,

3 Responses

Subscribe to comments with RSS.

  1. Excelente, segui publicando cosas de QT que son excelentes. Me ayudo mucho. Muchas gracias

    Yoni

    March 24, 2010 at 5:04 pm

  2. Gracias por tu aporte! esta muy completo y me ha sacado de apuros! salu2

    Erick Aldi

    June 14, 2012 at 2:13 am

  3. Excelente, muy completo felicitaciones, le animo a continuar compartiendo sus conocimientos, todo me fue de mucha ayuda, Gracias

    Pedro

    September 15, 2016 at 4:14 am


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: