Etter å ha "fiklet" litt med Qt-Creator og brukt C++ for første gang på lenge så må jeg ærlig innrømme og si det at det er mange fine klasser. Og en av klassene er veldig greie å venne seg til er QString. Med denne klassen kan man gjøre veldig mye med strenger som ellers ville ha knotet med. Det er vel egentlig bare 2 måter/metoder jeg har lyst til å skrive litt om. Dvs jeg vil sammenlikne 2 metoder for å illustrere lettvintheten med å bruke en klasse som QString. Jeg har ikke satt meg inn i std::string så veldig så jeg vet ikke hva den klassen er kapabel til, men det spiller ingen rolle. 

Jeg skal ta for meg en situasjon hvor klienten får tilsendt en streng med data som er avgrenset av tegnet '|' og'\n'. Dvs i denne formen:

"(type1)|synonym1|synonym2|synonym3|synonymN\n
(type2)|synonym1|synonym2|synonym3|synonymN\n
(typeM)|....".osv...

Og den er nullterminert. Skal være det iallefall. En gang i tiden skrev jeg nettsidene i C og brukte noe som heter qDecoder. Å skrive nettsider i C er ikke den mest effektive måten å produsere nettsider på men av nysgjerrighet så gjorde jeg det. Det fungerte helt fint, men det er noe med det at man er nødt til å kompilere for hver gang man skal gjøre en liten endring som ikke er så veldig effektivt for å si det sånn..men men..back to topic.

I index-fila på denne siden så er den noen grasale funksjoner som håndterer og "splitter" dataen i flere deler slik at man kan klikke på en link for å kunne søke på synonymer som er funnet av søkeordet. Nå vet ikke jeg om jeg gjorde ting på beste måte men det fungerte og det er det som teller. Her er koden:

while(get_str != NULL)
{
	get_str = strtok_r(NULL, tok, &dumy);
	if(get_str != NULL)
	{
		get_str2 = strtok_r(get_str, tok2, &dumy2);
		//	printf("%s<br/>\n", get_str);
		//	//first word should be (nound, adv or similar)
		printf("<br>Used as: <b>%s</b>: ", get_str2);
		get_str2 = strtok_r(NULL, tok2, &dumy2);
		strcpy(temp, get_str2);
		//get_str3 = strtok_r(temp, tok3, &dumy3);
		get_str3 = strchr(temp, '(');
		if(get_str3 != NULL)
		{
			get_str3 -=1;
			*get_str3 = NULL;
		}
		printf("<b><a href=\"%s%s%s\">%s</a></b>", ppath, temp, local, get_str2);
		while(get_str2 != NULL)
		{
			get_str2 = strtok_r(NULL, tok2, &dumy2);
			if(get_str2 != NULL)
			{
				strcpy(temp, get_str2);
				//get_str3 = strtok_r(temp, tok3, &dumy3);
				//printf("sendRequest returned: %s\n", get_str);
				get_str3 = strchr(temp, '(');
				if(get_str3 != NULL)
				{
					get_str3 -=1;
					*get_str3 = NULL;
				}
				printf("<b>, <a href=\"%s%s%s\">%s</a></b>", ppath, temp, local, get_str2);
			}
		}
	}

Det jeg skal fram til er at det ser ikke pent ut, og det er fryktelig uoversiktelig. Man kan selvfølgelig lage en funksjon slik at man slipper å se på alt dette hver gang man skal splitte en streng i mindre deler. Foruten å bruke php så er det fine løsninger i C++/Qt med klassen QString. Klienten jeg skrev vha Qt og Qt-Creator så har jeg bare splittet data-strengen en gang, men det illustrerer i det minste lettvindtheten med det hele.

Jeg bruker faktisk 2 klasser QString og QStringList. Den siste tar vare på alt sammen i ei ja...ei liste. Jeg tar med hele funksjonen slik at man ser det i en sammenheng.

//sets the QString received_data_buf and inserts into a list
int qtItreeClient::insertDataString(char* dt)
{
    if(dt == NULL)
        this->received_data_buf = QString((const char*)ccic->getDataString());
    else
        this->received_data_buf = QString((const char*)dt);
    if(!this->received_data_buf.isEmpty())
        this->data_list = this->received_data_buf.split(QString("\n"));
    return 0;
}

Og som man ser på linje 9. Lettere går det nesten ikke an å gjøre det. Og har jeg lyst til å dele strengen enda mer så er det jo bare å bruke samme funksjon på nytt. Dvs. medlems-funksjonen "split(...)". 

På en måte så kan man jo si at programmeringen blir kjedeligere, men sjansen for å gjøre feil er mindre, samt at det å jobbe med pekere kan være rotete og "farlig".

Det er en annen situasjonen i funksjonen "int ccIClient::readIData(void)" hvor jeg måtte endre på data-typen for at verdiene skulle bli riktig. Dvs. jeg fikk ikke lov til å bruke datatypen unsigned char*(pga av knvertering til QString), og da ble det rot i sy-sakene.
Her er koden fra den originale:

        id->response_type = *ptr++;
	id->data_type = *ptr++;

	a = (unsigned int)*ptr++;
	b = (unsigned int)*ptr++;
	c = (unsigned int)*ptr++;
	d = (unsigned int)*ptr++;
#ifdef __CMDIT_DEBUG
	printf("in readdata: a,b,c,d: %i %i %i %i \n", a, b, c, d);
#endif
	id->buf_size = MAKEULONG(a, b, c, d);
	id->data_index = *ptr;
	
	data = malloc(id->buf_size);
#ifdef __CMDIT_DEBUG
	printf("\nrett før siste read: %i", (int)id->buf_size);
#endif
	n = read(fd, data, id->buf_size);

For det første: pekeren ptr er definert som unsigned char*. Og blir gjort om til en unsigned int. Dette fungerte fint i C. Men i C++ ble jeg nødt til å initialisere pekeren som char* pga av lese funksjonen read(...). Så da endte det opp med følgende kode i C++

        rt = *ptr++;
        dt = *ptr++;
        a = *ptr++;
        b = *ptr++;
        c = *ptr++;
        d = *ptr++;
        buf_size = MAKEULONG(a, b, c, d);
        di = *ptr;
        received_data = new char[buf_size+4];
        client->waitForReadyRead(3000);
        n = client->read(received_data, buf_size+4);

Jeg personlig synes dette er litt merkelig. Ble nødt til å gjøre om a,b,c og d til unsigned char. Mao så lager man en unsigned long med 4 unsigned char's. Men når jeg debugger så ser jeg jo at kompilatoren bruker verdien av variabelen og 'tegnet'. Men igjen så er det eneste jeg kan si er at det fungerer og det er det viktigste.