[Kde-devel-es] Haciendo un "switch" con un QString

David García Garzón kde-devel-es@mail.kde.org
Wed, 22 Jan 2003 10:35:30 +0100


Desgraciadamente tienes razon, el switch nada mas funciona con enteros o 
equivalentes. La solucion cutre es hacer 'else if' anidados. Si quieres ir 
rapido puedes aprovechar el hecho de que conoces los posibles valores para 
hacer una comparacion dicotomica aunque el codigo queda muy dificil de 
mantener.

Tambien puedes calcular un valor de hash y hacer el switch con los valores de 
hash de las cadenas esperadas. Eso si, comprovando despues la cadena ya que 
pueden haber colisiones con cadenas invalidas.

switch(miFuncionDeHash(adifTab)) {
	case CALL_HASH: 
	if (adifTab=="CALL") {
		...
	}
	break;
...

Si la seleccion se ejecuta muchas veces por programa, igual te sale a cuenta 
construir, durante la inicializacion, un mapa o diccionario  de nombre -> 
valor entero y hacer el switch. A veces, en vez de hacerse el mapa con nombre 
-> entero, se hace directamente con nombre -> punteros a funciones con el 
codigo del switch. Con punteros a funcion el codigo queda mas expresivo, 
compacto i facil de mantener, aun asi, no siempre es tan optimo como puede 
parecer pues, al igual que pasa con las funciones virtuales, un salto a una 
funcion calculada para totalmente el pipeline del procesador.



On Dimarts 21 Gener 2003 19:09, Jaime Robles wrote:
> Buenas tardes a todos.
> A ver si alguien me puede decir como puedo hacer un "switch" con un
> QString... Estoy leyendo un fichero que contiene datos del estilo a:
> <fichero de datos>
> ADIF Export from Klog
> http://klog.berlios.de
> <EOH>
>
> <CALL:5>EA4TV <QSO_DATE:8>20030121 <TIME_ON:4>1153 <MODE:2>CW <BAND:3>80m
> <RST_SENT:3>599 <RST_RCVD:3>599 <TX_
> POWER:2>90 <QSL_RCVD:1>N <QSL_SENT:1>N <COMMENT:0><EOR>
>
> <CALL:5>EA7CD <QSO_DATE:8>20030121 <TIME_ON:4>1153 <MODE:3>SBB <BAND:3>10m
> <RST_SENT:3>599 <RST_RCVD:3>599 <TX
> _POWER:2>89 <QSL_RCVD:1>N <QSL_SENT:1>N <COMMENT:0><EOR>
> <fichero de datos>
>
> Y con el codigo que tengo debajo encuentro los "tags" que se marcan con
> <NOMBRE_DEL_TAG:Longitud_del_Dato>DATO
>
> Al final de un registro se encuentra un <EOR> que marca el final de ese
> registro y comienzo del siguiente (o no).
>
> Os he puesto un ejemplo de un fichero de datos que quiero analizar.
>
> Ahora la pregunta... En función de cada etiqueta es un dato... ¿Como hago
> el switch??? porque creo solo se pueden meter enteros... :-?
>
> A lo mejor hay alguna otra forma... pero no se como sin hacer uso intensivo
> de "if" que creo que no es la solucion.
>
> Gracias!
>
> El codigo que tengo es este:
>
> void Klog::adifReadLog(){
> //  QStringList lines;
> //  QString aux;
>   QFile file( "logadif.adi" );
>   if ( file.open( IO_ReadOnly ) ) {
>     QTextStream stream( &file );
>     QString line;
>     QString adifTab;
>     QString theData;
>     int len; // for the tab length
>     QString data = "";
>     int aux = 0;
>     while ( !stream.eof()  && (aux == 0)) {
>       data = stream.readLine();
>       if (data.upper().contains("<EOH>") != 0)
>         aux = 1;
>     }
>     data = ""; //
>     while (!stream.eof()){
>       data = stream.readLine();
>       if(!data.isEmpty()){
>         data = data.simplifyWhiteSpace().upper();
>         aux = data.contains('<');
>         cout << "\nAux: " << aux << endl;
>
>         QStringList fields = QStringList::split('<', data );
>
>         for (int a = 0; a < aux-1; a++){
>           if (fields[a].contains("<EOR>") == 0){
>             adifTab = fields[a].section(':',0,0);
>             len = (fields[a].section(':',1)).section('>',0,0).toInt();
>             theData = ((fields[a].section(':',1)).section('>',1));
>             theData.truncate(len);
>             switch (adifTab){
>               case "CALL":
>                 qso.setQrz(theData);
>               break;
>               case "QSO_DATE":
>               break;
>               case "TIME_ON":
>               break;
>               case "RST_RCVD":
>                 qso.setRstrx(theData.toInt());
>               break;
>               case "RST_SENT":
>               break;
>               case "BAND":
>               break;
>               case "MODE":
>               break;
>               case "TX_PWR":
>               break;
>               case "QSLSDATE":
>               break;
>               case "QSLRDATE":
>               break;
>               case "QSL_RCVD":
>               break;
>               case "QSL_SENT":
>               break;
>               case "QSL_VIA":
>               break;
>               case "ADDRESS":
>               break;
>               case "GRIDSQUARE":
>               break;
>               case "IOTA":
>               break;
>               case "OPERATOR":
>               break;
>               case "STATE":
>               break;
>               case "NAME":
>               break;
>               case "QTH":
>               break;
>               case "RX_PWR":
>               break;
>               case "STX":
>               break;
>               case "STX":
>               break;
>               default:
>               break;
>             }
>
>           }else{
>
>            // The tab is <EOR>
>           }
> //data.section( "**", 2, 2 ); // s == "surname"
>
>
>         }
>       //Klog::qrz = fields[2]
>
>         Klog::number++;
>       }
>     }
>     file.close();
>   }
>
> }

-- 
David ("Vokimon") García Garzón
(Work) dgarcia at iua dot upf anotherdot es
(Home) vokimon at wanadoo adot es
http://www.salleurl.edu/~is04069