D/Napisy
Z Wikibooks, biblioteki wolnych podręczników.
[edytuj] Napisy
Napisy w języku D są po prostu tablicami znaków. Do ich reprezentacji można używać typu char[] (string również istnieje, ale jest tylko aliasem do typu invariant(char)[]). Ciągi znaków domyślnie są tylko do odczytu (invariant). Dlatego w celu zapisania ich do zmiennej typu char[] wymagane jest utworzenie zapisywalnej kopii używając własności tablic dup. Dodatkowo dla kodowań UTF-16 oraz UTF-32 przeznaczone są typy wchar[] oraz dchar[].
[edytuj] Kodowanie napisów w D
Napisy w D są kodowane w systemie Unicode. Nie są również zakończone znakiem \0, dlatego - kiedy zakończenie zerem jest wymagane (a tak może być w niektórych funkcjach z C) to należy je dopisać.
Domyślnie napisy są kodowane w UTF-8 i są zapisywane w tablicach char[]. Możliwe jest również użycie kodowań UTF-16 (typ wchar[]) oraz UTF-32(dchar[]).
[edytuj] Typy literałów
[edytuj] Literały zwykłe, WYSIWYG i szesnastkowe
Najczęściej ciągi znaków zapisujemy w cudzysłowie, podobnie jak w innych językach programowania. Takie łańcuchy respektują sekwencje ucieczki i łamania wierszy:
"ab " // Ten łańcuch zawiera trzy znaki: a, b, i łamanie wiersza.
"ab\n" // Ten tak samo.
Oprócz tego D oferuje jeszcze inne typy literałów - łańcuchy WYSIWYG oraz szesnastkowe. Łańcuch WYSIWYG ignoruje sekwencje ucieczki, czyli - zgodnie z zasadą WYSIWYG (What You See Is What You Get = "To, co widzisz, jest tym, co dostajesz") - zawiera te znaki, które wpiszemy. Takie literały poprzedza się prefiksem r lub umieszcza między znakami `:
r"ab\n" // Łańcuch WYSIWYG. Zawiera 4 znaki - a, b, \ oraz n. `ab\n` // To też jest łańcuch WYSIWYG.
Łańcuch szesnastkowy umożliwia nam wprowadzanie znaków za pomocą kodów szesnastkowych. Poprzedzane są literą x:
x"af 20 3b" // Ten łańcuch zawiera znaki o kodach 0xaf (g), 0x20 (spację) oraz 0x3b (średnik).
Łańcuchy szesnastkowe ignorują białe znaki, więc można je wstawiać dla zwiększenia czytelności.
[edytuj] Literały char[], wchar[] i dchar[]
Aby określić typ danych reprezentowany przez literał, możemy dopisać przyrostek za cudzysłowem zamykającym:
"Ten łańcuch jest typu char[] (UTF-8)"c "Ten łańcuch jest typu wchar[] (UTF-16)"w "Ten łańcuch jest typu dchar[] (UTF-32)"d
Jeżeli nie podamy żadnego przyrostka, łańcuch będzie typu char[].
[edytuj] Porównywanie napisów
Do porównywania napisów używamy tych samych operatorów, co do porównywania liczb. Napisów możemy również używać w instrukcji switch, co nie jest możliwe np. w języku Java.
char[] c = "hello".dup;
if(c == "hello")
writefln("tak"); // Wypisze "tak"
switch(napis)
{
case "hello":
break;
default:
break;
}
[edytuj] Wycinanie
Z racji, że napis jest tablicą, wycinanie przebiega w identyczny sposób, jak w innych rodzajach tablic:
char[] tekst = "jakis tekst".dup; char[] fragment = tekst[6..11]; //fragment będzie zawierał: "tekst"
[edytuj] Moduł std.string
Język D oferuje również sporo funkcji przeznaczonych do wykonywania operacji na napisach. Funkcje te zawarte są w module std.string. Oto najważniejsze elementy tego modułu:
[edytuj] iswhite() - Sprawdzanie, czy znak jest biały
bool iswhite(dchar c);
Funkcja iswhite() służy do sprawdzania, czy dany znaj jest białym znakiem. Obsługuje wszystkie typy znakowe: char, wchar i dchar:
bool a = iswhite('a'); // false;
bool b = iswhite('\n'); // true;
[edytuj] icmp() - Porównywanie ignorujące wielość liter
int icmp(in char[] s1, in char[] s2);
Ta funkcja pozwala porównywać napisy ignorując wielkość liter. Zwracane wartości:
- <0, jeśli s1 jest mniejsze
- 0, jeśli s1 = s2
- >0, jeśli s2 jest mniejsze
Dokładniej, funkcja porównuje znaki na kolejnych pozycjach. Jeżeli na którejś pozycji są znaki są różne, zwraca różnicę kodów odpowiadających znaków z napisów s1 i s2. Jeżeli na wszystkich pozycjach znaki są takie same, zwraca zero.
[edytuj] toStringz() - Konwersja na ciągi znaków w stylu C
const(char)* toStringz(const(char)[] s);
Funkcja toStringz() konwertuje ciąg znaków do postaci znanej z C. Wynikowy ciąg znaków otrzymujemy w postaci stałej typu char*. Jest on również zakończony zerem.
[edytuj] find(), rfind(), ifind(), irfind() - wyszukiwanie w napisach
int find(in char[] s, dchar c);
int ifind(in char[] s, dchar c);
int rfind(in char[] s, dchar c);
int irfind(in char[] s, dchar c);
int find(in char[] s, in char[] sub);
int ifind(in char[] s, in char[] sub);
int rfind(in char[] s, in char[] sub);
int irfind(in char[] s, in char[] sub);
Powyższe osiem funkcji umożliwia wyszukiwanie znaków lub ciągów znaków w napisie. Argument s to ciąg znaków, w którym chcemy znaleźć sekwencję, zaś jako argument c lub sub podajemy szukany znak lub wyrażenie.
Funkcje find oraz ifind zwracają miejsce pierwszego wystąpienia szukanego wyrażenia, a rfind oraz irfind - ostatniego. Jeżeli wyrażenie nie zostanie znalezione, zwrócona zostanie wartość -1.
Funkcje o nazwach rozpoczynających się od "i" ignorują wielkość liter.
char[] tekst = "Hello World"; int index;
index = find(tekst, 'o'); // 4 index = rfind(tekst, 'o'); // 7 index = ifind(tekst, 'W'); // 6 index = irfind(tekst, 'W'); // też 6 index = find(tekst, "world"); // -1, wielkość liter się nie zgadza index = ifind(tekst, "world"); // 6, ifind ignoruje wielkość liter
[edytuj] tolower(), toupper(), capitalize(), capwords() - zamiana wielkości liter
string tolower(string s);
string toupper(string s);
string capitalize(string s);
string capwords(string s);
Te funkcje służą do zamiany wielkości liter:
- tolower - zamienia cały napis na małe litery.
- toupper - zamienia CAŁY NAPIS NA DUŻE LITERY.
- capitalize - zamienia Pierwszą literę na dużą, resztę na małe.
- capwords - zamienia Pierwszą Literę Każdego Wyrazu Na Dużą, pozostałe na małe.
[edytuj] join() - łączenie ciągów znaków
string join(in immutable(char)[][] words, string sep);
Ta funkcja łączy ciągi znaków w jeden, rozdzielając je napisem zawartym w argumencie sep. Pierwszy argument musi być tylko do odczytu:
invariant(char)[][] skladniki = ["Hello", "World"]; string res = join(skladniki, " "); // res = "Hello World"
[edytuj] split() - rozbijanie napisu na słowa
immutable(char)[][] split(string s);
immutable(char)[][] split(string s, string delim);
Powyższe funkcje zwracają w tablicy słowa składające się na dany napis. Pierwsza za "rozdzielacz" słów uznaje białe znaki, druga - parametr delim.
invariant char[][] words = split("Hello World"); // words = ["Hello" "World"]
[edytuj] splitlines() - rozbijanie napisu na linie
immutable(char)[][] splitlines(string s);
Rozbija napis na linie. Znaki \n oraz \r nie są zawarte w liniach.
[edytuj] strip(), stripl(), stripr() - usuwanie białych znaków na początku lub końcu
String stripl(String)(String s);
String stripr(String)(String s);
String strip(String)(String s);
Uwaga - są to funkcje szablonowe
Usuwa białe znaki na początku lub końcu napisu:
- stripl - tylko na początku
- stripr - tylko na końcu
- strip - po obu stronach
String res = strip!(String)(" Hello World "); // res = "Hello World"
[edytuj] startsWith(), endsWith() - sprawdzanie, czy łańcuch zaczyna się lub kończy odpowiednim ciągiem znaków
bool startsWith(A1, A2)(A1 longer, A2 shorter);
bool endsWith(A1, A2)(A1 longer, A2 shorter);
Uwaga - są to funkcje szablonowe
Sprawdza, czy wartość longer typu A1 zaczyna się (startsWith) lub kończy (endsWith) wartością shorter typu A2.
bool res = startsWith!(string, string)("Hello World", "Hello"); // res = true
[edytuj] replace() - zamienianie fragmentu ciągu znaków na inny
string replace(string s, string from, string to);
Zamienia ciąg znaków from na to w zmiennej s.
[edytuj] insert() - wstawianie ciągu znaków do innego
string insert(string s, size_t index, string sub);
Wstawia ciąg znaków sub do napisu s w miejscu określonym przez index.