Klávesové zkratky na tomto webu - základní
Přeskočit hlavičku portálu

Programování pro PalmOS počítače krok za krokem (28)

aktualizováno 
Minule jsme si uváděli příklady použití přemístitelných a nepřemístitelných bloků paměti. V následující tabulce shrneme rozdíly mezi oběma dvěma typy bloků paměti. Dokončíme si popis bloků paměti a povíme si o práci s řetězci v prostředí PalmOS.
  Nepřemístitelné bloky paměti Přemístitelné bloky paměti
Proměnná, kterou se na blok odkazujeme Adresa počátku bloku MemPtr Ovladač bloku MemHandle
Inicializace a zrušení funkcemi MemPtrNew(), MemPtrFree() funkcemi MemHandleNew(), MemHandleFree()
Ukládání a čtení dat Je možné ihned od adresy počátku bloku Pouze z uzamknutého bloku (mezi voláním funkce MemHandleLock() a MemHandleUnlock())
Změna velikosti funkce MemPtrResize() funkce MemHandleResize(), blok nesmí být uzamčen
Dotaz na velikost bloku paměti funkce MemPtrSize() funkce MemHandleSize()

Dosud popsané postupy zacházení s přemístitelnými a nepřemístitelnými bloky paměti se vztahovaly zatím pouze na dynamickou paměť. Pokud v naší aplikaci potřebujeme použít větší množství paměti, než kolik se nám vejde do oblasti dynamické paměti, musíme bloky paměti alokovat v oblasti úložné paměti. O práci s úložnou pamětí si povíme při popisu správce databází PalmOS v některé z příštích kapitol.

3.7. Funkce PalmOS pro zacházení s řetězci

Jádro operačního systému PalmOS v sobě obsahuje funkce pro práci s řetězci. Podobně jako v jazyce C/C++ jsou podporovány řetězce jako pole znaků libovolné délky ukončené znakem '\0'. Protože funkce pro práci s řetězci jsou již obsažené v jádru operačního systému, tak nepotřebujeme při překladu připojovat k naší aplikaci žádnou speciální knihovnu pro práci s řetězci.

Doporučované datové typy pro práci se znaky a s řetězci v PalmOS ve verzi 3.0 a vyšší jsou uvedeny v následující tabulce:

 standardní C/C++PalmOS
Jednotlivé znaky char nebo unsigned char (8bitový datový typ) WChar (16bitový datový typ, ve kterém mohou být uloženy i dvoubytové znaky UNICODE)
Řetězec
char text[100];
(pole 8bitových znaků)
Char text[100];
(pole osmibitových znaků, ve kterém však mohou být zařazeny i dvoubytové znaky UNICODE
Ukazatel na řetězec
char* ukazatel;
Char* ukazatel;

Doporučení používat pro uložení jednotlivých znaků 16bitový datový typ WChar místo 8bitového (Char) má základ v široké podpoře PalmOS pro jazyky používající nestandardní abecedy. Samotné řetězce jsou uloženy z důvodů úspory paměti jako pole 8bitových znaků Char a systémové funkce dovedou správně rozlišit jedno a dvoubytové znaky, které se v řetězcích nacházejí.


Char* s1 = "ahoj";    

// Deklarace řetězcové konstanty s hodnotou "ahoj". Tato konstanta
// zabírá v paměti 5 byte: 
// s1[0] = 'a' 
// s1[1] = 'h' 
// s1[2] = 'o' 
// s1[3] = 'j' 
// s1[4] = '\0'

WChar znak = s1[3]; // znak má hodnotu 'o'

Char s2[30];

// Deklarace řetězce, který může obsahovat nejvíce 29 znaků
// (poslední znak bude ukončující '\0')

Char* s3 = s1;

// s3 ukazuje na stejný řetězec jako s1 (obsahující "ahoj")

Funkce PalmOS pro práci s řetězci

Při psaní aplikací pro PalmOS doporučují vývojáři společnosti Palm, Inc. nepoužívat funkce standardní knihovny C/C++ (jako strlen(), strcat(), toupper() a podobně). Pokud kteroukoliv z těchto funkcí použijeme, bude při překladu k naší aplikaci připojena standardní knihovna C/C++, která zvětší velikost naší aplikace o 1-10 kB.

UInt16 StrLen(const Char* src)

Zjistí délku řetězce.

Vstupní parametry
  • src - adresa řetězce
Vrácená hodnota
  • délka řetězce = počet znaků (8bitových) před ukončujícím znakem '\0'. Jsou-li v řetězci vícebytové znaky, tak nemusí vrácená hodnota odpovídat skutečnému počtu znaků.

 

Char* StrCopy(Char* kam, const Char* odkud)

Zkopíruje jeden řetězec do druhého.

Vstupní parametry
  • odkud - adresa počátku zdrojového řetězce.
  • kam - adresa počátku řetězce, do kterého bude zdrojový řetězec kopírován (cílový řetězec).
Vrácená hodnota
  • ukazatel na cílový řetězec (kam)

Pokud se zdrojový i cílový řetězec překrývají, tak se může funkce StrCopy() chovat nepředvídatelně. Použití funkce je následující (pro připomenutí budu ve většině příkladů v této kapitole používat i bloky paměti):

Char* a = "abcde";            // řetězcová konstanta
Char b[100];
Char* c = (Char*)MemPtrNew(100); // můžeme použít i blok paměti 

n = StrLen(a);         // n bude rovné pěti

n = StrLen("");        // n bude rovno nule

StrCopy(b, a);         // b bude mít hodnotu "abcde"

StrCopy(c, "kocka");   // c bude mít hodnotu "kocka"

MemPtrFree((MemPtr)c); // nesmíme zapomenout uvolnit paměť

 

Char* StrNCopy(Char* cíl, const Char* zdroj, Int16 n)

Zkopíruje zdrojový řetězec na místo cílového. Ohlídá přitom, aby nebyla překročena největší délka cílového řetězce.

Vstupní parametry
  • zdroj - adresa počátku zdrojového řetězce.
  • cíl - adresa počátku řetězce, do kterého bude zdrojový řetězec kopírován (cílový řetězec).
  • n - maximální délka proměnné, ve které bude uložen cílový řetězec.
Vrácená hodnota
  • ukazatel na cílový řetězec (kam)

Po volání funkce StrNCopy() bude cílový řetězec dlouhý nejvýše (n - 1) znaků a bude ukončen znakem '\0'. Celý se tedy vejde do oblasti paměti o délce n byte. Tuto funkci je vhodné používat ve všech případech, kdy kopírujeme řetězce proto, aby nedocházelo k překročení maximální povolené délky řetězce. Funkce v následujícím rámečku zkopíruje text do oblasti přemístitelného bloku paměti a ohlídá si, aby nebyla překročena jeho délka:

void Kopiruj(MemHandle hKam, Char* odkud)
{
    StrNCopy((Char*)MemHandleLock(hKam), odkud, MemHandleSize(hKam));
    MemHandleUnlock(hKam);
}

Funkce StrCopy() a StrNCopy() jsou ekvivalenty funkcí strcpy() a strncpy() z knihovny řetězcových funkcí jazyka C/C++.

Char* StrCat(Char* cíl, const Char* text)

Spojí dva řetězce - zkopíruje řetězec text na konec řetězce cíl.

Vstupní parametry
  • cíl - adresa řetězce, na jehož konec bude připojen řetězec text
  • text - adresa připojovaného řetězce
Vrácená hodnota
  • ukazatel na řetězec cíl (to znamená na výsledný řetězec) obsahující spojené texty

Funkce StrCopy() a StrCat() vrací adresu výsledného řetězce - to je možné využít - například po volání

Char text[10];
StrCopy(text, StrCat("a", "b"))
obsahuje proměnná text text "ab".

Char* StrNCat(Char* cíl, const Char* text, Int16 n)

Spojí dva řetězce - zkopíruje řetězec text na konec řetězce cíl a ohlídá, aby se výsledný řetězec vešel do n byte.

Vstupní parametry
  • cíl - adresa řetězce, na jehož konec bude připojen řetězec text
  • text - adresa připojovaného řetězce
  • n - maximální délka proměnné cíl, která nebude při kopírování překročena
Vrácená hodnota
  • ukazatel na řetězec cíl (to znamená na výsledný řetězec) obsahující spojené texty

Při kopírování řetězců zadaných uživatelem nebo takových, u kterých neznáme přesně jejich délku, se doporučuje použít funkcí StrNCopy() a StrNCat(). Tím zabráníme chybám, které vzniknou při překročení místa v paměti vyhrazeného proměnné.

Char* StrToLower(Char* cíl, const Char* zdroj)

Zkopíruje řetězce a převede všechny znaky na malá písmena.

Vstupní parametry
  • zdroj - adresa počátku zdrojového řetězce.
  • cíl - adresa počátku řetězce do kterého bude zdrojový řetězec kopírován (cílový řetězec).
Vrácená hodnota
  • podobně jako funkce StrCopy() vrací tato funkce adresu proměnné cíl, do které je text zkopírován

Na systémech, které podporují mezinárodní znaky (PalmOS 3.3 a vyšší) nebo v aplikacích, které speciálně připravíme pro zpracování mezinárodních znaků na starších operačních systémech, převádí tato funkce správně i česká akcentovaná písmena. O správné lokalizaci našich aplikací si povíme později.

Int16 StrCompare(const Char* s1, const Char* s2)
Int16 StrCaselessCompare(const Char* s1, const Char* s2)

Porovná řetězce s1 a s2. Funkce StrCaselessCompare() porovnává bez ohledu na velká a malá písmena.

Vstupní parametry
  • s1 - adresa prvního řetězce
  • s2 - adresa druhého řetězce
Vrácená hodnota
  • -1 - s1 je v abecedě před s2
  • 0 - řetězce jsou totožné
  • 1 - s1 je v abecedě za s2

Pro správné abecední porovnání dvou řetězců je nutné volat obě tyto funkce - nejprve StrCaselessCompare() a poté teprve funkci StrCompare() jako v následujícím příkladu:

Int16 PorovnejAbecedne(Char* s1, Char* s2)
{
  Int16 vysledek = StrCaselessCompare(s1, s2);
  
  return vysledek == 0 ? StrCompare(s1, s2) : vysledek;
}

 

Int16 StrNCompare(const Char* s1, const Char* s2, UInt32 n)
Int16 StrNCaselessCompare(const Char* s1, const Char* s2, Int32 n)

Porovná prvních n (nebo méně) znaků s1 a s2. Funkce StrNCaselessCompare() porovnává bez ohledu na velká a malá písmena.

Vstupní parametry
  • s1 - adresa prvního řetězce
  • s2 - adresa druhého řetězce
  • n - počet znaků, které budou porovnávány
Vrácená hodnota
  • -1 - s1 (resp. jeho prvních n znaků) je v abecedě před s2
  • 0 - prvních n znaků s1 a s2 je totožných
  • 1 - s1 (resp. jeho prvních n znaků) je v abecedě za s2

Ve verzích operačního systému, které podporují mezinárodní znaky řadí porovnávací funkce české akcentované znaky správně.

Char* StrStr(const Char* kde, const Char* co)

Vyhledá první výskyt řetězce co v řetězci kde.

Vstupní parametry
  • kde - text, ve kterém vyhledáváme
  • co - text, který hledáme v řetězci kde
Vrácená hodnota
  • NULL - v řetězci kde se nevyskytuje řetězec co
  • adresa počátku prvního výskytu řetězce co v řetězci kde

 

Char* StrChr(const Char* kde, WChar znak)

Vyhledá první výskyt znaku znak v řetězci kde.

Vstupní parametry
  • kde - text, ve kterém vyhledáváme
  • znak -zkak, který hledáme v řetězci kde
Vrácená hodnota
  • NULL - v řetězci kde se nevyskytuje řetězec co
  • adresa počátku prvního výskytu řetězce co v řetězci kde

Předáme-li funkci StrChr() znak, který bude větší než 255, tak zobrazí chybovou hlášku. Bude-li znak roven '\0', tak nebude ve verzi PalmOS 1.0 nalezen správně.


Příště si dokončíme popis funkcí pro práci s řetězci popisem funkcí pro převod čísel na text.



Nejčtenější

Google posílá vzkaz Evropské komisi. Takhle se bude bránit

Protikartelová komisařka Margrethe Vestagerová.

Google se s obří pokutou od Evropské komise nehodlá smířit. Firma se proti ní odvolá a chce Komisi dokázat, že systém...

Rekordní pokuta pro Google, za dominanci Androidu zaplatí 112 miliard

Ilustrační snímek

Evropská komise uložila internetovému gigantu Google další pokutu. Firma by měla platit za to, že zneužívá dominantního...



Nový supersmartphone vysune kameru a nahrává uživatele bez jeho vědomí

Vivo NEX

V rámci právě skončeného mistrovství světa ve fotbalu byla hrací plocha obklopena panely s reklamami na nový čínský...

Jeden z nejočekávanějších mobilů roku. Nokia 8110 je chytrá jen trochu

Nokia 8110 4G

Retro model Nokia 8110 4G je možná jedním z nejočekávanějších mobilů letošního roku. V Česku se začal prodávat počátkem...

Ten určitě neznáte. Toto je úplně první dotykový mobil v Evropě

Alcatel One Touch Com a Sharp MC-G1

Před dvaceti lety se na trh dostal jedinečný mobilní telefon. Alcatel One Touch Com byl jedním z prvních přístrojů s...

Další z rubriky

Za 23 korun vám aplikace fotku z iPhonu ukáže až za tři dny

Netradiční fotoaplikace Gudak vás donutí nad fotkami zase přemýšlet

Vnímání fotografie se za posledních pár let výrazně změnilo. Díky záznamovým médiím již totiž nemusíme přemýšlet nad...

Sem chodí smartphony umřít. Aplikaci lze použít jen s vybitou baterií

Die With Me

Aplikace s názvem Umři se mnou má velmi neobvyklé omezení. Nemůžete ji zapnout, pokud máte telefon nabitý víc než na...

Na aplikace alternativních taxi útočí virus. Pase po údajích ke kartám

Virus pro Android

Uživatelé mobilních aplikací alternativních taxi včetně aplikace Uber by měli být obezřetní. Ohrožuje je totiž nový...

Najdete na iDNES.cz