Písmena s diakritikou
Emin farmářský obchod teď prodává i dýně a pšenici a takové názvy potřebují zvláštní péči. Tady je proč.
Počítač ukládá text jako řadu bajtů, malých čísel od 0 do 255. Texty ve vašich programech jsou, stejně jako většina textů na světě, v kódování UTF-8: každé písmeno anglické abecedy, každá číslice, mezera i interpunkce zabírá jeden bajt, ale písmeno s diakritikou, třeba č nebo ý, zabírá dva (a některé znaky, třeba emoji, dokonce čtyři). Funkce pro řetězce v Lua o písmenech nevědí nic: počítají a stříhají bajty. V textu bez diakritiky je jeden bajt jeden znak, takže si ničeho nevšimnete. S diakritikou ano, a to na čtyřech místech.
1. Délka. # i len počítají bajty. Znaky spočítá utf8.len z knihovny utf8, kterou Lua má právě na tohle:
local slovo = "dýně"
print(#slovo, slovo:len(), utf8.len(slovo))Vypíše:
6 6 42. Velká a malá písmena. upper a lower mění jen písmena od a do z; písmena s diakritikou nechají, jak jsou:
print(("farma Slunečnice"):upper())
print(("ŘEPA"):lower())Vypíše:
FARMA SLUNEčNICE
ŘepaKdyž takové slovo potřebujete velkými písmeny, napište ho tak rovnou do kódu: "SLUNEČNICE".
3. Stříhání. Pozice v sub jsou také bajty. V "dýně" zabírá ý pozice 2 a 3, takže první dvě písmena jsou sub(1, 3) a sub(1, 2) rozstřihne ý v půlce:
local slovo = "dýně"
print(slovo:sub(1, 3))
print(slovo:sub(1, 2))
print(slovo:sub(1, 2) == "dý")Vypíše:
dý
d�
falsePolovina písmena není žádný znak, a tak se místo ní vypíše �. Totéž platí pro reverse, který prohodí dva bajty každého písmena s diakritikou: ("dýně"):reverse() vrátí ��n��d. Bezpečně můžete stříhat na pozicích, které vám dal find (to jsou také bajty), a se zápornými pozicemi, když konec textu diakritiku nemá.
4. Šířky. %-10s doplní text na 10 bajtů, takže slovo dostane o mezeru méně za každé písmeno s diakritikou:
print(("%-10s|"):format("mrkev"))
print(("%-10s|"):format("dýně"))Vypíše:
mrkev |
dýně |Pomůže doplnit mezery ručně: tolik, kolik je šířka mínus počet znaků. Udělá to malá funkce:
local function doplnit(text, sirka)
return text .. (" "):rep(sirka - utf8.len(text))
end
print(doplnit("mrkev", 10) .. "|")
print(doplnit("dýně", 10) .. "|")Vypíše:
mrkev |
dýně |Když je text delší než šířka, vyjde počet záporný a rep vrátí prázdný text, takže se nic neořízne, stejně jako u %-10s.
Stejný problém s diakritikou mají i vzory v dalším cvičení; uvidíte ho tam. Pravidlo pro všechno: vypisovat, spojovat a hledat texty s diakritikou můžete vždy bez obav. Když počítáte, stříháte, zarovnáváte nebo měníte velikost písmen, myslete na bajty.
Jak psát:
Pokyny
Spusťte program: dva řádky seznamu jsou posunuté. Abyste viděli proč, přidejte nad seznam samostatný cyklus, který vypíše počet znaků každého názvu, spočítaný pomocí utf8.len:
mrkev: 5
dýně: 4
pšenice: 7Teď seznam opravte. Místo %-10s doplňte každý název mezerami na 10 znaků sami, pomocí rep a utf8.len; hmotnost zůstane formátovaná pomocí %6.2f. Seznam se srovná:
mrkev 12.50 kg
dýně 30.00 kg
pšenice 6.75 kgZačněte programovat zdarma
5/9