34

--- Przewodnik po języku C# --- Struny

Jeśli chodzi o zwykłe programowanie, string typ danych ciągu jest jednym z najważniejszych w C#. Ten typ definiuje i obsługuje ciągi znaków. W wielu innych językach programowania ciąg znaków jest tablicą znaków. A w C# ciągi są obiektami. Dlatego typ ciągu jest jednym z typów referencyjnych.

Budowa rzędów

Najłatwiejszym sposobem skonstruowania ciągu znaków jest użycie literału ciągu. Na przykład w następującym wierszu kodu zmienna referencji ciągu str jest przypisana do literału ciągu:

String str = "Przykładowy ciąg";

W tym przypadku zmienna str jest inicjowana sekwencją znaków „Example String”. Obiekt typu string można również utworzyć z tablicy typu char. Na przykład:

Char chararray = ("e", "x", "a", "m", "p", "l", "e"); string str = nowy string(chararray);

Po utworzeniu obiektu typu string można go używać wszędzie tam, gdzie potrzebny jest ciąg tekstu w cudzysłowie.

Trwałość ciągu

Co dziwne, zawartość obiektu typu string nie może być modyfikowana. Oznacza to, że po utworzeniu sekwencji znaków nie można jej zmienić. Ale to ograniczenie przyczynia się do wydajniejszej implementacji ciągów znaków. Dlatego ta na pierwszy rzut oka oczywista wada faktycznie zamienia się w zaletę. Tak więc, jeśli potrzebujesz ciągu jako odmiany istniejącego ciągu, to w tym celu powinieneś utworzyć nowy ciąg zawierający wszystkie niezbędne zmiany. A ponieważ nieużywane obiekty tekstowe są automatycznie gromadzone w „śmieciach”, nie musisz się nawet martwić o los niepotrzebnych ciągów.

Należy jednak podkreślić, że zmienne referencyjne typu string (czyli obiekty typu string) podlegają zmianom, a zatem mogą odnosić się do innego obiektu. Ale zawartość samego obiektu tekstowego nie zmienia się po jego utworzeniu.

Rozważ przykład:

Static void addNewString() ( string s = "To jest mój pociągnięcie"; s = "To jest nowy pociągnięcie"; )

Skompilujmy aplikację i załadujmy powstały zestaw do narzędzia ildasm.exe. Rysunek przedstawia kod CIL, który zostanie wygenerowany dla metody void addNewString():

Zwróć uwagę na wielokrotne wywołania kodu operacji ldstr (ładowanie ciągu). Ten kod operacji ldstr w CIL powoduje załadowanie nowego obiektu ciągu na zarządzaną stertę. W rezultacie poprzedni obiekt, który zawierał wartość „To jest moje pociągnięcie”, zostanie ostatecznie zebrany.

Praca ze strunami

W klasie System.Ciąg dostarczany jest zestaw metod określania długości danych znakowych, wyszukiwania podciągu w bieżącym ciągu, konwertowania znaków z duże litery do dołu i odwrotnie itd. Przyjrzymy się tej klasie bardziej szczegółowo w dalszej części.

Pole, indeksator i właściwość klasy String

Klasa String ma zdefiniowane jedno pole:

Publiczny statyczny ciąg tylko do odczytu Pusty;

Pole Empty oznacza pusty ciąg, tj. ciąg, który nie zawiera znaków. Różni się to od pustej referencji String, która jest po prostu tworzona do nieistniejącego obiektu.

Ponadto klasa String definiuje pojedynczy indeksator tylko do odczytu:

Znak publiczny to ( get; )

Ten indeksator umożliwia uzyskanie znaku o określonym indeksie. Indeksowanie ciągów, podobnie jak tablice, zaczyna się od zera. Obiekty String są trwałe i nie zmieniają się, więc ma sens, że klasa String obsługuje indeksator tylko do odczytu.

Wreszcie klasa String definiuje pojedynczą właściwość tylko do odczytu:

Public int Długość ( get; )

Właściwość Length zwraca liczbę znaków w ciągu. Poniższy przykład pokazuje użycie indeksatora i właściwości Length:

Korzystanie z systemu; class Przykład ( static void Main() ( string str = "Prosty ciąg"; // Pobranie długości ciągu i szóstego znaku ciągu za pomocą indeksatora Console.WriteLine("Długość ciągu wynosi (0), szósty znak to "(1)"" , str.Długość, str); ) )

Operatory klas ciągów

Klasa String przeciąża następujące dwa operatory: == i !=. Operator == służy do testowania równości dwóch ciągów znaków. Kiedy operator == jest stosowany do odwołań do obiektów, zwykle sprawdza, czy oba odwołania odnoszą się do tego samego obiektu. A gdy operator == jest stosowany do odwołań do obiektów typu String, zawartość samych ciągów jest porównywana pod kątem równości. To samo dotyczy operatora !=. Gdy jest stosowany do odwołań do obiektów typu String, zawartość samych ciągów jest porównywana pod kątem nierówności. Jednocześnie inne operatory relacyjne, w tym =, porównują odwołania do obiektów typu String w taki sam sposób, jak do obiektów innych typów. Aby sprawdzić, czy jeden ciąg jest większy od drugiego, należy wywołać metodę Compare() zdefiniowaną w klasie String.

Jak zostanie później wyjaśnione, wiele rodzajów porównań ciągów znaków wykorzystuje informacje kulturowe. Nie dotyczy to jednak operatorów == i !=. W końcu po prostu porównują wartości porządkowe znaków w ciągach. (Innymi słowy, porównują wartości znaków binarnych, które nie zostały zmodyfikowane przez normy kulturowe, tj. ustawienia regionalne). Dlatego te operatory wykonują porównania ciągów w sposób niewrażliwy na wielkość liter i kulturę.

Metody klasy ciągów

W poniższej tabeli wymieniono niektóre z bardziej interesujących metod tej klasy, pogrupowane według celu:

Metody ciągów
metoda Wersje strukturalne i przeciążone Zamiar
Porównanie ciągów
Porównywać() public static int Compare(string strA, string strB)

Public static int Compare(ciąg strA, ciąg strB, bool ignoreCase)

Public static int Compare(string strA, string strB, StringComparison ComparisonType)

Public static int Compare (ciąg strA, ciąg strB, bool ignoreCase, kultura CultureInfo)

Metoda statyczna, porównuje ciąg strA z ciągiem strB. Zwraca wartość dodatnią, jeśli strA jest większe niż strB; ujemna, jeśli strA jest mniejsze niż strB; i zero, jeśli ciągi strA i strB są równe. Porównanie jest wrażliwe na wielkość liter i kulturowo.

Jeśli parametr ignoreCase przyjmuje logiczne prawda, porównanie nie uwzględnia różnic między wielkimi i małymi literami. W przeciwnym razie różnice te są brane pod uwagę.

Parametr compareType określa określony sposób porównywania ciągów. Klasa CultureInfo jest zdefiniowana w przestrzeni nazw System.Globalization.

public static int Compare(string strA, int indexA, string strB, int indexB, int length)

Public static int Compare(string strA, int indexA, string strB, int indexB, int length, bool ignoreCase)

Public static int Compare(string strA, int indexA, string strB, int indexB, int length, StringComparison ComparisonType)

Public static int Compare(string strA, int indexA, string strB, int indexB, int length, bool ignoreCase, CultureInfo kultura)

Porównuje części ciągów strA i strB. Porównanie rozpoczyna się od elementów string strA i strB i obejmuje liczbę znaków określoną przez parametr length. Metoda zwraca wartość dodatnią, jeśli część strA jest większa niż część strB; wartość ujemna, jeśli część strA jest mniejsza niż część strB; i zero, jeśli porównywane części ciągów strA i strB są równe. Porównanie jest wrażliwe na wielkość liter i kulturowo.

porównajPorządkowe() public static int CompareOrdinal(ciąg strA, ciąg strB)

Public static int CompareOrdinal(string strA, int indexA, string strB, int indexB, int count)

Działa tak samo jak metoda Compare(), ale bez względu na ustawienia lokalne

Porównać do() public int CompareTo(wartość obiektu)

Porównuje ciąg wywołujący z ciągiem reprezentującym obiekt wartości. Zwraca wartość dodatnią, jeśli ciąg wywołujący jest większy niż wartość ciągu; wartość ujemna, jeśli ciąg wywołujący jest mniejszy niż ciąg wartości; i zero, jeśli porównywane ciągi są równe

public int CompareTo(string strB)

Porównuje ciąg wywołujący ze strB

Równa się() public override bool Equals(object obj)

Zwraca wartość logiczną true, jeśli ciąg wywołujący zawiera tę samą sekwencję znaków, co ciąg znaków reprezentujący obiekt. Wykonuje porównanie porządkowe, z uwzględnieniem wielkości liter, ale kulturowo niewrażliwe

public bool Równe (wartość ciągu)

Public bool Równe (wartość ciągu, StringComparison typ porównania)

Zwraca wartość logiczną true, jeśli ciąg wywołujący zawiera tę samą sekwencję znaków, co wartość ciągu. Przeprowadzane jest porównanie porządkowe, z uwzględnieniem wielkości liter, ale kulturowo niewrażliwe. Parametr ComparisonType definiuje określony sposób porównywania ciągów

public static bool Równe (ciąg a, ciąg b)

Public static bool Równe (ciąg a, ciąg b, StringComparison ComparisonType)

Zwraca wartość logiczną true , jeśli string a zawiera tę samą sekwencję znaków co string b . Przeprowadzane jest porównanie porządkowe, z uwzględnieniem wielkości liter, ale kulturowo niewrażliwe. Parametr ComparisonType definiuje określony sposób porównywania ciągów

Konkatenacja (połączenie) ciągów
Konkat() publiczny ciąg statyczny Concat(ciąg str0, ciąg str1);

publiczny static string Concat(params string values);

Łączy oddzielne instancje ciągu w jeden ciąg (konkatenacja)
Szukaj w ciągu
Zawiera() public bool Zawiera(wartość ciągu) Metoda, która pozwala określić, czy ciąg zawiera określony podciąg (wartość)
Zaczynać z() public bool StartsWith(wartość ciągu)

Public bool StartsWith(wartość ciągu, StringComparison ComparisonType)

Zwraca wartość logiczną true, jeśli ciąg wywołujący zaczyna się od podciągu wartości. W przeciwnym razie zwracana jest wartość logiczna false. Parametr ComparisonType określa, w jaki sposób ma zostać przeprowadzone wyszukiwanie.

Kończy się() public bool EndsWith(wartość ciągu)

Public bool EndsWith(wartość ciągu, StringComparison ComparisonType)

Zwraca wartość logiczną true, jeśli ciąg wywołujący kończy się podciągiem wartości. W przeciwnym razie zwraca wartość logiczną false. Parametr ComparisonType definiuje konkretną metodę wyszukiwania

Indeks() public int IndexOf (wartość znaku)

Public int IndexOf(wartość ciągu)

Znajduje pierwsze wystąpienie danego podciągu lub znaku w ciągu. Jeśli szukany znak lub podciąg nie zostanie znaleziony, zwracane jest -1.

public int IndexOf(wartość znaku, int startIndex)

Public int IndexOf(wartość ciągu, int startIndex)

Public int IndexOf(wartość znaku, int startIndex, liczba int)

Public int IndexOf(wartość ciągu, int startIndex, liczba int)

Zwraca indeks pierwszego wystąpienia znaku lub wartości podciągu w ciągu wywołującym. Wyszukiwanie rozpoczyna się od elementu określonego w indeksie startIndex i obejmuje liczbę elementów określoną przez parametr count (jeśli został określony). Metoda zwraca -1, jeśli poszukiwany znak lub podciąg nie został znaleziony

LastIndexOf() Przeciążone wersje są podobne do metody IndexOf()

To samo co IndexOf, ale znajduje ostatnie wystąpienie znaku lub podciągu zamiast pierwszego

IndeksDowolnego() public int IndexOfAny(char anyOf)

Public int IndexOfAny(char anyOf, int startIndex)

Public int IndexOfAny(char anyOf, int startIndex, int count)

Zwraca indeks pierwszego wystąpienia dowolnego znaku w tablicy anyOf znalezionego w ciągu wywołującym. Wyszukiwanie rozpoczyna się od elementu określonego przez index startIndex i obejmuje liczbę elementów określoną przez parametr count (jeśli istnieje). Metoda zwraca -1, jeśli nie znaleziono dopasowania dla żadnego ze znaków w tablicy anyOf. Wyszukiwanie odbywa się w sposób porządkowy

LastIndexOfAny Przeciążone wersje są podobne do metody IndexOfAny()

Zwraca indeks ostatniego wystąpienia dowolnego znaku w tablicy anyOf znalezionej w ciągu wywołującym

Dzielenie i łączenie ciągów
Rozdzielać public string Split(params char separator)

Public string Split(params char separator, int count)

Metoda, która zwraca tablicę ciągów z podciągami obecnymi w tym wystąpieniu wewnątrz, oddzielonymi od siebie elementami z określonej tablicy znaków lub ciągów.

Pierwsza forma metody Split() dzieli ciąg wywołujący na jego części składowe. Wynikiem jest tablica zawierająca podciągi pobrane z ciągu wywołującego. Znaki ograniczające te podciągi są przekazywane w tablicy separatorów. Jeśli tablica separatora jest pusta lub odnosi się do pustego ciągu, spacja jest używana jako separator podciągu. A w drugiej formie Ta metoda zwraca liczbę podciągów określonych przez parametr count.

public string Split (separator znaków params, opcje StringSplitOptions)

Public string Split(separator stringów, opcje StringSplitOptions)

Public string Split(params char separator, int count, StringSplitOptions opcje)

Public string Split(separator ciągu, liczba int, opcje StringSplitOptions)

Pierwsze dwie formy metody Split() dzielą ciąg wywołujący na części i zwracają tablicę zawierającą podciągi uzyskane z ciągu wywołującego. Znaki oddzielające te podciągi są przekazywane w tablicy separatorów. Jeśli tablica separatora jest pusta, jako separatora używana jest spacja. A w trzeciej i czwartej formie tej metody zwracana jest liczba wierszy ograniczona parametrem count.

Ale we wszystkich formularzach parametr options określa określony sposób obsługi pustych ciągów, które są generowane, gdy dwa ograniczniki sąsiadują ze sobą. Wyliczenie StringSplitOptions definiuje tylko dwie wartości: Nic oraz UsuńPusteWpisy. Jeśli parametr options ma wartość None, wówczas w końcowym wyniku podziału zostaną uwzględnione puste ciągi. oryginalny ciąg. A jeśli parametr options jest ustawiony na RemoveEmptyEntries, puste ciągi są wykluczane z końcowego wyniku podziału oryginalnego ciągu.

Dołączyć() public statyczny ciąg Join(separator ciągu, wartość ciągu)

Publiczny statyczny ciąg Join(separator ciągu, wartość ciągu, int startIndex, liczba int)

Konstruuje nowy ciąg, łącząc zawartość tablicy ciągów.

Pierwsza forma metody Join() zwraca ciąg składający się z połączonych podciągów przekazanych w tablicy wartości. Druga forma również zwraca ciąg składający się z podciągów przekazanych w tablicy wartości, ale są one połączone ze sobą określoną liczbę zliczeń, zaczynając od elementu tablicy wartości. W obu formach każdy kolejny wiersz jest oddzielony od poprzedniego wierszem separatora określonego przez parametr separator.

Linie do napełniania i przycinania
przycinać() publiczny ciąg Trim()

Public string Trim(params char trimChars)

Metoda, która umożliwia usunięcie wszystkich wystąpień określonego zestawu znaków z początku i końca bieżącego ciągu.

Pierwsza forma metody Trim() usuwa spacje wiodące i końcowe z ciągu wywołującego. Druga forma tej metody usuwa początkowe i końcowe wystąpienia w wywołującym ciągu znaków z tablicy trimChars. Obie formy zwracają wynikowy ciąg.

PadW Lewo() public string PadLeft(int totalWidth)

Publiczny ciąg PadLeft(int totalWidth, char paddingChar)

Umożliwia dopełnienie ciągu znakami po lewej stronie.

Pierwsza forma metody PadLeft() wprowadza spacje po lewej stronie ciągu wywołującego, dzięki czemu jego całkowita długość wynosi równa wartości parametr totalWidth. W drugiej postaci tej metody znaki wskazane przez parametr paddingChar są wprowadzane po lewej stronie ciągu wywołującego, tak aby jego całkowita długość była równa wartości parametru totalWidth. Obie formy zwracają wynikowy ciąg. Jeśli wartość parametru totalWidth jest mniejsza niż długość ciągu wywołującego, zwracana jest kopia niezmodyfikowanego ciągu wywołującego.

PadPrawo() Podobne do PadLeft()

Umożliwia uzupełnienie ciągu znakami po prawej stronie.

Wstawianie, usuwanie i zastępowanie wierszy
Wstawić() public string Insert(int startIndex, string value)

Służy do wstawiania jednego ciągu do drugiego, gdzie wartość jest ciągiem, który ma zostać wstawiony do ciągu wywołującego w indeksie startIndex. Metoda zwraca wynikowy ciąg.

Usunąć() ciąg publiczny Remove(int startIndex)

Ciąg publiczny Usuń (int startIndex, int count)

Służy do usuwania części sznurka. W pierwszej postaci metody Remove() usuwanie jest wykonywane począwszy od lokalizacji określonej przez index startIndex i kontynuując do końca ciągu. A w drugiej postaci tej metody liczba znaków określona przez parametr count jest usuwana z ciągu, zaczynając od miejsca określonego przez indeks startIndex.

Zastępować() public string Replace(char oldChar, char newChar)

Ciąg publiczny Replace(ciąg staraWartość, ciąg NowaWartość)

Służy do zastąpienia części sznurka. Pierwsza forma metody Replace() zastępuje wszystkie wystąpienia oldChar w ciągu wywołującym na newChar. W drugiej formie tej metody wszystkie wystąpienia ciągu znaków staraWartość w ciągu wywołującym są zastępowane ciągiem NowaWartość.

Zmiana przypadku
Górny() ciąg publiczny ToUpper()

Zamienia wszystkie litery w ciągu wywołującym na wielkie litery.

Obniżyć() ciąg publiczny ToLower()

Sprawia, że ​​wszystkie litery w ciągu wywołującym są małe.

Pobieranie podciągu z ciągu
Podciąg() public string Substring(int startIndex)

Public string Substring (int startIndex, int length)

W pierwszej postaci metody Substring() podciąg jest wyodrębniany z lokalizacji wskazanej przez parametr startIndex do końca ciągu wywołującego. A w drugiej postaci tej metody wyodrębniany jest podciąg składający się z liczby znaków określonej przez parametr length, począwszy od miejsca wskazanego przez parametr startIndex.

Poniższy przykład programu wykorzystuje kilka z powyższych metod:

Korzystanie z systemu; za pomocą System.Collections.Generic; za pomocą System.Linq; za pomocą System.Text; namespace ConsoleApplication1 ( class Program ( static void Main(string args) ( // Porównaj pierwsze dwa ciągi string s1 = "to jest ciąg"; string s2 = "to jest tekst, to jest ciąg"; if (String.CompareOrdinal (s1, s2) != 0) Console.WriteLine("Ciągi s1 i s2 nie są równe"); if (String.Compare(s1, 0, s2, 13, 10, true) == 0) Console.WriteLine( "Zawierają jednak ten sam tekst"); // Łączenie ciągów Console.WriteLine(String.Concat("\n" + "Jeden, dwa ","trzy, cztery")); // Wyszukiwanie w ciągu // Pierwsze wystąpienie of substring if (s2. IndexOf("this") != -1) Console.WriteLine("Słowo \"to\" zostało znalezione w linii, jest to "+"na: (0) pozycji", s2. IndexOf("this")); // Ostatnie wystąpienie podciągu if (s2.LastIndexOf("this") != -1) Console.WriteLine("Ostatnie wystąpienie \"tego\" to " + "at ( 0) position", s2.LastIndexOf("this" )); // Szukaj z tablicy znaków char myCh = ("S","x","t"); if (s2.IndexOfAny(myCh) != -1) Console.WriteLine("Jeden ze znaków z tablicy ch "+" znaleziony w bieżącym bieżąca linia na pozycji (0)", s2.IndexOfAny(myCh)); // Sprawdź, czy ciąg zaczyna się od podanego podciągu if (s2.StartsWith("to jest tekst") == true) Console.WriteLine("Znaleziono podciąg!"); // Sprawdź, czy ciąg zawiera podciąg // na przykładzie określania ciągu OS użytkownika myOS = Environment.OSVersion.ToString(); if (myOS.Contains("NT 5.1")) Console.WriteLine("Twój system operacyjny System Windows XP"); else if (myOS.Contains("NT 6.1")) Console.WriteLine("Your system operacyjny Windows 7"); Konsola.ReadLine(; ) ) )

Trochę o porównaniu ciągów w C#

Ze wszystkich operacji przetwarzania ciągów znaków jest to prawdopodobnie najczęściej wykonywane porównanie jednego ciągu z drugim. Zanim przyjrzymy się którejkolwiek z metod porównywania ciągów, należy podkreślić, że: porównanie ciągów można wykonać w .NET Framework na dwa główne sposoby:

    Po pierwsze, porównanie może odzwierciedlać zwyczaje i normy określonego środowiska kulturowego, które często są kontekstami kulturowymi, które mają zastosowanie, gdy program jest wykonywany. Jest to standardowe zachowanie dla niektórych, choć nie wszystkich metod porównawczych.

    Po drugie, porównanie można przeprowadzić niezależnie od ustawień środowiska kulturowego tylko na wartościach porządkowych znaków tworzących ciąg. Ogólnie rzecz biorąc, niewrażliwe kulturowo porównanie ciągów wykorzystuje porządek leksykograficzny (i cechy językowe) w celu określenia, czy jeden ciąg jest większy, mniejszy lub równy innemu ciągowi. W porównaniu porządkowym ciągi są po prostu uporządkowane na podstawie niezmodyfikowanej wartości każdego znaku.

Ze względu na różnice w sposobie porównywania ciągów między kulturami i porównaniami porządkowymi oraz implikacje każdego takiego porównania zdecydowanie zalecamy korzystanie z najlepszych rozwiązań oferowanych obecnie przez firmę Microsoft. W końcu wybranie niewłaściwego sposobu porównywania ciągów może spowodować, że program będzie działał niepoprawnie, gdy będzie działał w środowisku innym niż to, w którym został stworzony.

Wybór sposobu porównywania ciągów znaków to bardzo ważna decyzja. Zgodnie z ogólną zasadą i bez wyjątku należy wybrać porównanie ciągów wrażliwe na kulturę, jeśli ma ono na celu wyświetlenie wyniku użytkownikowi (na przykład w celu wyświetlenia serii ciągów posortowanych w porządku leksykograficznym). Ale jeśli ciągi zawierają stałe informacje, które nie mają być modyfikowane ze względu na różnice kulturowe, takie jak nazwa pliku, słowo kluczowe, adres witryny internetowej lub wartość związaną z bezpieczeństwem, należy wybrać porównanie ciągów porządkowych. Oczywiście specyfika rozwijanej aplikacji będzie dyktować wybór odpowiedniego sposobu porównywania ciągów znaków.

Klasa String udostępnia różne metody porównywania ciągów, które wymieniono w powyższej tabeli. Najbardziej wszechstronną z nich jest metoda Compare(). Umożliwia porównanie dwóch ciągów znaków w całości lub w części, z uwzględnieniem wielkości liter lub bez uwzględniania wielkości liter, w sposób określony przez parametr typu Porównanie ciągów, a także informacje kulturowe dostarczone przez parametr typu Informacje o kulturze.

Te przeciążenia metody Compare(), które nie zawierają parametru typu StringComparison, wykonują porównanie ciągów znaków z uwzględnieniem wielkości liter i kultury. A w tych przeciążonych wariantach, które nie zawierają parametru typu CultureInfo, informacje o kulturze są określane przez bieżące środowisko uruchomieniowe.

Typ StringComparison to wyliczenie definiujące wartości przedstawione w poniższej tabeli. Korzystając z tych wartości, możesz organizować porównania ciągów, które odpowiadają potrzebom Twojej aplikacji. Dlatego dodanie parametru typu StringComparison rozszerza możliwości metody Compare() i innych metod porównania, takich jak Equals(). Umożliwia także jednoznaczne określenie sposobu porównywania ciągów.

Ze względu na różnice między kulturowo wrażliwymi porównaniami ciągów i porównaniami porządkowymi ważne jest, aby w tym zakresie zachować jak największą dokładność.

Wartości zdefiniowane w wyliczeniu StringComparison
Oznaczający Opis
Aktualna Kultura Porównanie ciągów odbywa się przy użyciu bieżących ustawień kultury
Bieżąca kultura Ignoruj ​​sprawę Porównanie ciągów jest wykonywane przy użyciu bieżących ustawień kultury, ale nie uwzględnia wielkości liter
Niezmienna Kultura Porównanie ciągów odbywa się za pomocą niezmiennych, tj. uniwersalne dane o środowisku kulturowym
Kultura niezmienna Ignoruj ​​przypadek Porównanie ciągów odbywa się za pomocą niezmiennych, tj. uniwersalne dane kulturowe i niewrażliwe na wielkość liter
Porządkowy Porównanie ciągów odbywa się za pomocą wartości porządkowych znaków w ciągu. W takim przypadku porządek leksykograficzny może zostać naruszony i konwencje akceptowane w określonym środowisku kulturowym są ignorowane
Porządkowe IgnorujCase Porównanie ciągów odbywa się za pomocą wartości porządkowych znaków w ciągu, ale bez uwzględniania wielkości liter

W obu przypadkach metoda Compare() zwraca wartość ujemną, jeśli pierwszy porównywany ciąg jest mniejszy niż drugi; wartość dodatnia, jeśli pierwszy porównywany ciąg jest większy niż drugi; i wreszcie zero, jeśli oba porównywane ciągi są równe. Chociaż metoda Compare() zwraca zero, jeśli porównywane ciągi są równe, ogólnie lepiej jest użyć metody Equals() lub operatora ==, aby określić, czy ciągi znaków są równe.

Faktem jest, że metoda Compare() określa równość porównywanych ciągów na podstawie ich kolejności sortowania. Na przykład, jeśli ciągi są porównywane kulturowo, oba ciągi mogą być takie same w kolejności sortowania, ale zasadniczo nie są równe. Domyślnie równość ciągów jest określana w metodzie Equals() na podstawie wartości porządkowych znaków, a nie kulturowo. W związku z tym domyślnie oba ciągi są porównywane w tej metodzie pod kątem bezwzględnej równości znak po znaku, podobnie jak w przypadku operatora ==.

Pomimo dużej wszechstronności metody Compare(), do prostego porównywania porządkowego ciągów znaków łatwiej jest użyć metody CompareOrdinal(). Na koniec należy pamiętać, że metoda CompareTo() porównuje tylko ciągi w sposób wrażliwy kulturowo.

Poniższy program demonstruje użycie metod Compare(), Equals(), CompareOrdinal() oraz operatorów == i != do porównywania ciągów znaków. Zauważ, że pierwsze dwa przykłady porównania wyraźnie pokazują różnice między kulturowo wrażliwymi porównaniami ciągów a angielskimi porównaniami porządkowymi:

Korzystanie z systemu; class Przykład ( static void Main() ( string str1 = "alpha"; string str2 = "Alpha"; string str3 = "Beta"; string str4 = "alpha"; string str5 = "alpha, beta"; int wynik; / / Najpierw zademonstruj różnicę między porównaniem ciągów zależnych od kultury a wynikiem porównania porządkowego = String.Compare(str1, str2, StringComparison.CurrentCulture); Console.Write("Porównanie ciągów zależne od kultury: "); if (wynik 0 ) Console .WriteLine(str1 + " jest większa niż " + str2); w przeciwnym razie Console.WriteLine(str1 + "is " + str2); wynik = String.Compare(str1, str2, StringComparison.Ordinal); Console.Write("Porównanie porządkowe lines: "); if (wynik 0) Console.WriteLine(str1 + " jest większe niż " + str2); else Console.WriteLine(str1 + "jest równe " + str4); // Użyj wyniku metody CompareOrdinal() = String.CompareOrdinal( str1, str2); Console.Write("Porównaj ciągi za pomocą CompareOrdinal():\n"); if (wynik 0) Console.WriteLine(str1 + " większe niż " + str2); else Console.WriteLine (str 1 + "jest równe" + str4); Konsola.WriteLine(); // Określ równość ciągów za pomocą operatora == // To jest porządkowe porównanie ciągów znaków if (str1 == str4) Console.WriteLine(str1 + " == " + str4); // Wykryj nierówność linii za pomocą operatora != if(str1 != str3) Console.WriteLine(str1 + " != " + str3); if(str1 != str2) Console.WriteLine(str1 + " != " + str2); Konsola.WriteLine(); // Wykonaj porządkowe porównanie ciągów bez uwzględniania wielkości liter za pomocą metody Equals() if(String.Equals(str1, str2, StringComparison.OrdinalIgnoreCase)) Console.WriteLine("Porównywanie ciągów znaków za pomocą metody Equals() z parametrem " + "OrdinalIgnoreCase : \n" + str1 + " jest równe " + str2); Konsola.WriteLine(); // Porównaj części ciągów if(String.Compare(str2, 0, str5, 0, 3, StringComparison.CurrentCulture) > 0) ( Console.WriteLine("Porównywanie ciągów na podstawie bieżącej kultury:" + "\n3 pierwsze znaki ciągu „+ str2 +” jest większe niż pierwsze 3 znaki ciągu „+ str5; )) )

Uruchomienie tego programu daje następujący wynik:

Nie ma oddzielnego typu danych „ciąg znaków” w języku C. Praca z łańcuchami jest realizowana przy użyciu tablic jednowymiarowych typu char, czyli ciąg znaków to jednowymiarowa tablica znaków zakończona bajtem null.

Bajt zerowy to bajt, którego każdy bit jest równy zero, podczas gdy stała znakowa '\0' (terminator linii lub terminator zerowy) jest zdefiniowana dla bajtu zerowego. Dlatego jeśli ciąg musi zawierać k znaków, to w opisie tablicy należy podać k+1 elementów.

Na przykład znak a; - oznacza, że ​​ciąg może zawierać sześć znaków, a ostatni bajt jest zarezerwowany na zero.

Stała łańcuchowa to zestaw znaków zawartych w podwójne cudzysłowy. Na przykład:

char S="Praca z łańcuchami";

Nie ma potrzeby jawnego określania znaku '\0' na końcu stałej łańcuchowej.

Podczas pracy z ciągami wygodnie jest używać wskaźników, na przykład:

x = "BSUIR";

x = (i>0)? "dodatni": (i<0)? "отрицательное":"нулевое";

Przypomnij sobie, że do wprowadzania ciągów powszechnie używa się dwóch standardowych funkcji:

scanf()- wprowadza wartości dla zmiennych łańcuchowych ze specyfikatorem wejściowym %s przed pojawieniem się pierwszego znaku „spacji” (znak „&” nie musi być podawany przed identyfikatorem danych ciągu);

dostaje ()- wpisanie wiersza ze spacjami wewnątrz tej linii kończy się naciśnięciem klawisza ENTER.

Obie funkcje automatycznie kończą ciąg bajtem null.

Linie są wyprowadzane przez funkcje printf() lub puts() aż do pierwszego bajtu zerowego ('\0'):

printf() nie przesuwa kursora po wyjściu na początek nowej linii;

stawia () automatycznie przesuwa kursor po wyprowadzeniu informacji o łańcuchu na początek nowej linii.

Na przykład:

printf(" Wprowadź ciąg bez spacji: \n");

scanf("%s",Str);

puts("Wprowadź ciąg");

Pozostałe operacje na ciągach są wykonywane przy użyciu standardowych funkcji bibliotecznych, których prototypy są opisane w pliku string.h. Przyjrzyjmy się najczęściej używanym funkcjom.

funkcja int strlen(char *S) zwraca długość ciągu (liczbę znaków w ciągu), ignorując kończący bajt null.

char *S1=”Mińsk!\0”, S2=”BSUIR-Hurra!”;

printf(“%d, %d.”, strlen(S1), strlen(S2));

Wynik tej sekcji programu:

funkcja int strcpy(char *S1, char *S2) - kopiuje zawartość ciągu S2 do ciągu S1.

Funkcjonować strcat(char *S1, char *S2) - łączy ciąg S2 z ciągiem S1 i umieszcza go w tablicy, w której był ciąg S1, a ciąg S2 nie jest zmieniany. Bajt null, który zakończył ciąg S1 jest zastępowany pierwszym znakiem ciągu S2.

funkcja int strcmp(char *S1, char *S2) porównuje ciągi S1 i S2 i zwraca wartość<0, если S10 jeśli S1>S2; =0 jeśli ciągi są równe, tj. zawierać taką samą liczbę identycznych znaków.

Funkcje do konwersji ciągu S na liczbę:

Liczba całkowita: int Atoi(znak*S);

Długa liczba całkowita: długa atol(znak*S);

Prawdziwe: podwójne atof(znak*S);

w przypadku błędu funkcje te zwracają 0.

Funkcje do konwersji liczby V na ciąg S.

»Wiarygodna agencja SEO w Indiach może zwiększyć przychody małych firm

80% użytkowników szuka w Google i innych wyszukiwarkach przed dokonaniem zakupu, a ponad 50% zapytań generowanych przez wyszukiwarki zostaje przekonwertowanych. Te dwie statystyki potwierdzają znaczenie optymalizacji pod kątem wyszukiwarek. Istnieje wiele takich statystyk i faktów, które jasno pokazują: każda mała, średnia lub duża firma potrzebuje profesjonalnych usług SEO. Małe firmy i startupy często borykają się z problemami budżetowymi. Mogą skorzystać z pomocy dowolnej godnej zaufania agencji SEO z Indii, aby uzyskać najlepszą usługę SEO w swoim budżecie, aby zwiększyć swoje przychody.
Wyszukiwanie ma ogromny wpływ na umysły konsumentów. Według różnych statystyk udostępnionych przez głównych ekspertów ds. optymalizacji pod kątem wyszukiwarek na różnych autoryzowanych stronach internetowych, takich jak Search Engine Land, Moz, SEO Journal, Digital Marketers India, Hubspot itp. SEO przechwytuje większość potencjalnych klientów. Również leady pochodzące z organicznych wyników wyszukiwania mają wyższy współczynnik konwersji. Te statystyki i zachowania konsumentów wyraźnie pokazują, że najlepsza usługa SEO nie jest luksusem, ale koniecznością dla każdej firmy.
Aby ominąć konkurencję i zwiększyć rozwój biznesu, każda organizacja musi korzystać z usług Search Engine Optimization. Duże marki mogą zainwestować wystarczająco dużo pieniędzy w specjalistyczną usługę SEO oferowaną przez czołową firmę SEO lub specjalistę SEO, ale właściciele małych firm często godzą się na jakość tej usługi ze względu na mniejszy budżet. To trudny fakt, że małe firmy i start-upy w końcu zostawiają możliwości, które można stworzyć dzięki profesjonalnej usłudze SEO lub skorzystaniu z taniej usługi SEO, która nie przynosi żadnych pozytywnych rezultatów.
Właściciele małych firm i startupy mogą korzystać z profesjonalnych usług SEO nawet przy ograniczonym budżecie. Najlepszym rozwiązaniem jest znalezienie godnej zaufania firmy SEO z siedzibą w Indiach. W Indiach jest wielu ekspertów SEO, którzy współpracują z agencją marketingu cyfrowego i oferują najlepsze w branży usługi. Mogą zapewnić wymagane usługi SEO w Twoim budżecie. Płace można negocjować z agencją SEO Indie, aby uzyskać lepsze usługi po niższych stawkach. Jednak nie daj się nabrać na tanią usługę SEO, która kosztuje mniej i obiecuje dawać więcej, ponieważ wiedza specjalistyczna odbywa się na własny koszt. Musisz zapoznać się z portfolio lub zadać odpowiednie pytania przed zawarciem umowy z firmą dla swojej firmy.
Eksperci SEO w Indiach znają się na najlepszych praktykach optymalizacji wyszukiwarek. Ponadto w Indiach jest kilku specjalistów SEO, takich jak Ash Vyas, którzy specjalizują się w tworzeniu najlepszej strategii optymalizacji wyszukiwarek dla firmy o określonym budżecie. Specjaliści SEO stworzą jasny plan, a także podzielą się oczekiwanymi rezultatami. W ten sposób możesz być dobrze świadomy swojej inwestycji i zwrotów. Pomaga to w podjęciu lepszej decyzji biznesowej.
Dobrym pomysłem jest jak najszybsze znalezienie i zawarcie umowy z godną zaufania firmą SEO z Indii, która oferuje najlepsze usługi SEO. Możesz również zacząć od małego budżetu i ograniczonych działań, aby zacząć indeksować swoje strony internetowe i poprawiać słowa kluczowe w wyszukiwarkach. Nie czekaj na idealny czas lub dzień, kiedy będziesz miał tysiące dolarów na zainwestowanie w najlepsze usługi SEO. Wczesne rozpoczęcie pracy pomoże Ci uzyskać szybsze wyniki, gdy możesz agresywnie stosować swoje podejście marketingowe. Godna zaufania firma SEO z siedzibą w Indiach pomoże Ci określić Twoje obecne i przyszłe plany, aby uzyskać dobre wyniki. Więcej zindeksowanych stron poprawiło rankingi i wiarygodną markę Twojej firmy stworzoną dzięki ciągłym profesjonalnym praktykom SEO, podwoi zapytania, biznes i przychody. Każda mała firma może zacząć od dwucyfrowej inwestycji w profesjonalne usługi SEO. Istnieje wiele agencji SEO w Indiach, które oferują niski budżet, ale wynikają z usług zorientowanych na Search Engine Optimization.

ankiety z wygnania

  • CraigWew

    12.04.2018

    »Znaczenie nawiązania relacji z klientem w zakresie nieruchomości i sprzedaży ogólnej

    Znaczenie nawiązania relacji z klientem.
    Na nawiązanie relacji z klientem trzeba zapracować i traktować je jako bardzo integralną część procesu sprzedaży.
    Aby skłonić klienta i siebie do relacji na zasadzie jeden do jednego, wiążą się dwie rzeczy!
    Po pierwsze, musisz być świadomy i być tam! Po drugie, musisz zrozumieć, że podczas tego procesu wystąpią dwa różne etapy.
    A-Bądź tam- co to znaczy?
    o Większość ludzi tak naprawdę nie słucha drugiej osoby podczas rozmowy. Na ogół są tak zajęci formułowaniem następnej odpowiedzi lub stwierdzenia, że ​​prawdopodobnie nie są w stanie naprawdę słuchać.
    o Jeśli to brzmi jak ty, bycie tam oznacza zamknij się i słuchaj!
    B-Jaki jest pierwszy lub początkowy etap?
    o Generalnie masz tylko kilka minut, aby ugruntować się w umyśle klientów jako osoba, z którą chcą mieć do czynienia.
    o W razie wątpliwości najlepiej jest najpierw zadać pytania, które wyciągną je i porozmawiają o sobie.
    o Zawsze bezpiecznie jest występować jako profesjonalista – nie mam na myśli stoickiego czy oschłego, ale kogoś, kto wie, co robi, mówi i wygląda dobrze.
    C-Pozostałe etapy
    o W miarę upływu czasu, poprzez rozmowę i pytania, które będą mieli, albo ustalisz swoje umiejętności, albo nie.
    o Miej świadomość, że prawdopodobnie będą cię mierzyć przez jakiś czas. Dobrą wiadomością jest to, że w pewnym momencie, jeśli odniesiesz sukces w nawiązaniu kontaktu, zrelaksują się i oboje możecie skoncentrować się na znalezieniu lub sprzedaży domu.
    Co jeszcze może mi pomóc w nawiązaniu kontaktu?
    o Próbując zrozumieć różne typy osobowości, a następnie mówiąc i zadając właściwe pytania.
    o Jeśli masz dobre relacje (nadajesz się na tej samej długości fali co klient), wtedy sprzedaż w zasadzie się skończyła, teraz to tylko kwestia znalezienia odpowiedniego domu lub wypełnienia dokumentów ofertowych.
    A co z różnymi osobowościami?
    o Ponieważ nie jest to książka o psychiatrii, na razie rozumiem tylko dwa główne typy.
    o Są ludzie introwertyczni i ekstrawertyczni.
    o Znasz typ. Pomyśl o trzech znanych Ci osobach, które pasują do każdej klasyfikacji.
    A co z mową ciała i wzorcami mowy?
    o Jeśli mówią szybko lub wolno, spróbuj naśladować ich wzorce mowy.
    o Jeśli mówią głośno lub cicho, zrób to samo. Czy pochylają się do przodu czy do tyłu?
    o Nie trzeba dodawać, że na ten temat napisano wiele książek. Po prostu pamiętaj, że jest to ważny czynnik — zwłaszcza, gdy siedzisz w sali konferencyjnej lub w czyimś domu omawiasz umowę o wartości 400 000 USD.
    Rozwijanie relacji to umiejętność, której można się nauczyć i doskonalić.
    o Wszyscy mieliśmy do czynienia ze sprzedawcą, który nam coś sprzedał, a mimo to nie czuliśmy, że jesteśmy sprzedawani. Powodem jest to, że sprawił, że poczułeś się komfortowo tam, gdzie im ufałeś.
    Jak budujemy relacje?
    o Używaj oczu i uszu i zadawaj pytania. wytłumaczyć
    o Użyj oczu:
    Spójrz na ich ubiór – ich samochód – ich rzeczy osobiste i naprawdę mam na myśli patrz na nich i rozszyfruj, co to ci o nich mówi.
    o Użyj uszu:
    o Słuchaj tego, co mówią i zadawaj pytania, aby dotrzeć do sedna ich prawdziwej MOTYWACJI!
    Teraz podczas całej tej rozmowy prawdopodobnie odkryjesz jedną lub dwie rzeczy, które masz z nimi wspólne. (Rodzina, obszary geograficzne, wędkarstwo itp.) Kiedy natkniesz się na wspólną płaszczyznę, daj im znać, że jesteś zaznajomiony, a następnie poświęć chwilę na przedyskutowanie tego z nimi.
    Jaki jest cel?
    o Gdy zaakceptują Cię jako jednego z nich, będziesz mieć naprawdę świetne doświadczenie w sprzedaży, ponieważ teraz pracujesz razem, a potem jako zespół — nie jesteś już sprzedawcą, a teraz zajmujesz stanowisko doradcze .
    o Pamiętaj, że klient albo pozwoli, albo nie pozwoli Ci wejść do swojego świata. Jeśli to zrozumiesz i naprawdę ciężko pracujesz, aby stać się wobec niego empatycznym, możesz zdobyć pozycję zaufania. W większości przypadków zobaczysz, jak się rozluźniają (mowa ciała), gdy tak się dzieje, gdy jesteś w drodze.
    o Aby to zilustrować, czy kiedykolwiek wygłosiłeś przemówienie i zauważyłeś, że kiedy w końcu nawiązałeś kontakt z publicznością, przytakną z aprobatą. Te rzeczy mogą wydawać się banalne, ale tak nie jest.
    Podsumowując, jeśli możesz zdobyć zaufanie klientów, sprzedaż produktu lub usługi jest znacznie łatwiejsza, a doświadczenie może być przyjemne dla wszystkich zaangażowanych.
    Zawsze pamiętaj, że wygrana/wygrana to najlepsza sytuacja.

Współczesny standard C++ definiuje klasę z funkcjami i właściwościami (zmiennymi) do organizowania pracy z łańcuchami (w klasycznym języku C nie ma łańcuchów jako takich, są tylko tablice znaków):

#włączać

#włączać

#włączać

Aby pracować z ciągami, musisz również uwzględnić standardową przestrzeń nazw:

Korzystanie z przestrzeni nazw std;

W przeciwnym razie będziesz musiał podać wszędzie deskryptor klasy std::string zamiast string.

Poniżej znajduje się przykład programu, który działa z łańcuchem (nie działa w starych kompilatorach zgodnych z C!):

#włączać #włączać #włączać używając standardowej przestrzeni nazw; int main() (ciąg s = "Test"; s.insert(1,"!"); cout<< s.c_str() << endl; string *s2 = new string("Hello"); s2->kasuj(s2->end()); Cout<< s2->c_str(); cin.get(); zwróć 0; )

Główne cechy, które posiada klasa string:

  • inicjalizacja za pomocą tablicy znaków (wbudowany ciąg) lub innego obiektu typu string . Wbudowany typ nie ma drugiej możliwości;
  • kopiowanie jednej linii do drugiej. Dla typu wbudowanego musisz użyć funkcji strcpy();
  • dostęp do poszczególnych znaków ciągu do czytania i pisania. We wbudowanej tablicy odbywa się to za pomocą operacji indeksowania lub adresowania pośredniego za pomocą wskaźnika;
  • porównywanie dwóch ciągów pod kątem równości. W przypadku typu wbudowanego używane są funkcje rodziny strcmp();
  • konkatenacja (konkatenacja) dwóch ciągów, dająca wynik albo jako trzeci ciąg, albo zamiast jednego z oryginalnych. W przypadku typu wbudowanego używana jest funkcja strcat(), ale aby uzyskać wynik w nowej linii, należy użyć kolejno funkcji strcpy() i strcat(), a także zadbać o alokację pamięci;
  • wbudowane środki do określania długości łańcucha (funkcje składowe klasy size() i l ength()). Jedynym sposobem sprawdzenia długości wbudowanego ciągu znaków jest obliczenie go za pomocą funkcji strlen();
  • możliwość sprawdzenia, czy ciąg jest pusty.

Przyjrzyjmy się bliżej tym podstawowym funkcjom.

Inicjalizacja ciągu opisując i Długość łańcucha(bez końcowego terminatora zerowego):

String st("Mój ciąg\n"); Cout<< "Длина " << st << ": " << st.size() << " символов, включая символ новой строки\n";

Ciąg może być również pusty:

Ciąg st2;

Aby sprawdzić, czy czy ciąg jest pusty?, możesz porównać jego długość z 0:

if (!st.size()) // pusty

lub użyj metody empty(), która zwraca true dla pustego ciągu i false dla niepustego:

if (st.empty()) // puste

Trzecia forma tworzenia ciągu inicjuje obiekt typu string z innym obiektem tego samego typu:

Ciąg st3(st);

Łańcuch st3 jest inicjowany łańcuchem st . Jak możemy się upewnić, że te ciągi pasują? Użyjmy operatora porównania (==):

Jeśli (st == st3) // inicjalizacja się powiodła

Jak skopiuj jedną linię do drugiej? Za pomocą zwykłego operatora przypisania:

st2 = st3; // skopiuj st3 do st2

Do konkatenacja ciągów używany jest operator dodawania (+) lub operator dodawania-przypisania (+=). Niech podane zostaną dwie linie:

Ciąg s1("cześć, "); ciąg s2("świat\n");

Możemy otrzymać trzeci ciąg składający się z konkatenacji pierwszych dwóch, a więc:

Ciąg s3 = s1 + s2;

Jeśli chcemy dodać s2 na koniec s1 , musimy napisać:

S1 += s2;

Operacja dodawania może łączyć obiekty klasy strunowy nie tylko między sobą, ale także ze stringami typu wbudowanego. Możesz przepisać powyższy przykład, aby znaki specjalne i znaki interpunkcyjne były reprezentowane przez wbudowany typ char * , a znaczące słowa były obiektami klasy string:

Const char *pc = ", "; ciąg s1("cześć"); ciąg s2("świat"); ciąg s3 = s1 + pc + s2 + "\n"; Cout<< endl << s3;

Takie wyrażenia działają, ponieważ kompilator "wie", jak automatycznie konwertować obiekty typu wbudowanego na obiekty klasy string . Możliwe jest również proste przypisanie wbudowanego ciągu do obiektu ciągu:

Ciąg s1; const char *pc = "tablica znaków"; s1=szt; // prawo

Odwrotna transformacja to nie działa. Próba wykonania następującej wbudowanej inicjalizacji ciągu typu spowoduje błąd kompilacji:

Znak*str = s1; // błąd kompilacji

Aby wykonać tę konwersję, musisz jawnie wywołać funkcję członkowską o nazwie c_str() ("ciąg C"):

Const char *str = s1.c_str();

Funkcja c_str() zwraca wskaźnik do tablicy znaków zawierającej ciąg obiektu ciągu, tak jak we wbudowanym typie ciągu. Słowo kluczowe const tutaj zapobiega „niebezpiecznej” możliwości w nowoczesnych środowiskach wizualnych bezpośredniej modyfikacji zawartości obiektu za pomocą wskaźnika.

Do poszczególne postacie obiekt typu string , podobnie jak typ wbudowany, można uzyskać za pomocą operacji indeksowania. Na przykład, oto fragment kodu, który zastępuje wszystkie kropki podkreśleniami:

String str("www.disney.com"); int rozmiar = str.rozmiar(); dla (int i = 0; i< size; i++) if (str[i] == ".") str[ i ] = "_"; cout << str;

Replace(str.begin(), str.end(), ".", "_");

To prawda, że ​​nie jest tu użyta metoda replace klasy string, ale algorytm o tej samej nazwie:

#włączać

Ponieważ obiekt ciągu zachowuje się jak kontener, można do niego zastosować inne algorytmy. Pozwala to rozwiązywać problemy, których nie rozwiązują bezpośrednio funkcje klasy string.

Poniżej znajduje się krótki opis głównych operatorów i funkcji klasy string, linki w tabeli prowadzą do opisów w języku rosyjskim w Internecie. Pełniejszą listę możliwości klasy string można znaleźć na przykład w Wikipedii lub cplusplus.com.

Określanie znaków w ciągu

operator=

przypisuje wartości do ciągu

przydzielać

przypisuje znaki do ciągu

Dostęp do poszczególnych postaci

w

uzyskanie określonego znaku ze sprawdzaniem indeksu poza granicami

operator

uzyskanie określonego znaku

przód

uzyskanie pierwszego znaku

plecy

uzyskanie ostatniego znaku

dane

zwraca wskaźnik do pierwszego znaku ciągu

c_str

zwroty niemodyfikowalny Tablica znaków C zawierająca znaki ciągu

Sprawdzanie pojemności sznurka

pusty

sprawdza, czy ciąg jest pusty

rozmiar
długość

zwraca liczbę znaków w ciągu

największy rozmiar

zwraca maksymalną liczbę znaków

rezerwa

rezerwuje miejsce do przechowywania

Operacje na sznurku

jasne

czyści zawartość ciągu

wstawić

wstawianie znaków

usuwać

usuwanie znaków

push_back

dodanie znaku na końcu łańcucha

pop_back

usuwa ostatni znak

dodać

operator+=

dodaje znaki na końcu ciągu

porównywać

porównuje dwie struny

zastąpić

zastępuje każde wystąpienie określonego znaku

substr

zwraca podciąg

Kopiuj

kopiuje znaki

Zmień rozmiar

zmienia liczbę przechowywanych znaków

Smyczki. Wejście/wyjście liniowe. Sformatowane wejścia/wyjścia. Przetwarzanie napisów przy użyciu standardowych funkcji języka C. Praca z pamięcią.

1.1. Deklarowanie i inicjowanie ciągów.

Ciąg znaków to tablica znaków, która kończy się pustym znakiem „\0”. Ciąg znaków jest zadeklarowany jako normalna tablica znaków, na przykład

znak s1; // ciąg dziewięcioznakowy

znak*s2; // wskaźnik do napisu

Różnica między wskaźnikami s1 i s2 polega na tym, że wskaźnik s1 jest nazwaną stałą, podczas gdy wskaźnik s2 jest zmienną.

Stałe łańcuchowe są ujęte w podwójne cudzysłowy, w przeciwieństwie do znaków, które są ujęte w pojedyncze cudzysłowy. Na przykład,

„To jest sznurek”.

Długość stałej ciągu nie może przekraczać 509 znaków zgodnie ze standardem. Jednak wiele implementacji pozwala na dłuższe ciągi.

Podczas inicjowania łańcuchów lepiej nie określać wymiaru tablicy, kompilator zrobi to, licząc długość łańcucha i dodając do niego jeden. Na przykład,

char s1 = „To jest ciąg.”;

W języku programowania C istnieje duża liczba funkcji do pracy z łańcuchami, których prototypy są opisane w plikach nagłówkowych stdlib.hi string.h. Praca z tymi funkcjami zostanie omówiona w kolejnych akapitach.

1.2. Wejście/wyjście liniowe.

Aby wprowadzić ciąg z konsoli, użyj funkcji

znak* dostaje(znak*str);

który zapisuje ciąg do adresu str i zwraca adres ciągu wejściowego. Funkcja zatrzymuje wejście, jeśli napotka znak '\n' lub EOF (koniec pliku). Znak nowej linii nie jest kopiowany. Na końcu czytanej linii umieszczany jest bajt zerowy. W przypadku powodzenia funkcja zwraca wskaźnik do czytanej linii, a w przypadku niepowodzenia wartość NULL.

Aby wyprowadzić ciąg do konsoli, użyj standardowej funkcji

int puts (const char *s);

który zwraca liczbę nieujemną w przypadku sukcesu i EOF w przypadku niepowodzenia.

Prototypy funkcji gets i puts są opisane w pliku nagłówkowym stdio.h.

#włączać

printf("Ciąg wejściowy: ");

1.3. Sformatowane wejścia/wyjścia.

Aby sformatować dane wejściowe z konsoli, użyj funkcji

int scanf (const char *format, ...);

który zwraca liczbę jednostek danych odczytanych w przypadku sukcesu i EOF w przypadku niepowodzenia. Parametr format musi wskazywać ciąg formatu, który zawiera specyfikacje formatu wejściowego. Liczba i typy argumentów występujących po ciągu formatu muszą być zgodne z liczbą i typami formatów wejściowych określonych w ciągu formatu. Jeśli ten warunek nie jest spełniony, wynik funkcji jest nieprzewidywalny.

Spacja, "\t" lub "\n" znaki w ciągu formatu opisują jeden lub więcej pustych znaków w strumieniu wejściowym, które obejmują następujące znaki: spacja, '\t', '\n', '\v', '\f'. Funkcja scanf pomija znaki null w strumieniu wejściowym.

Literalne znaki w ciągu formatu, z wyjątkiem znaku %, wymagają dokładnie tych samych znaków, aby pojawiły się w strumieniu wejściowym. Jeśli nie ma takiego znaku, scanf zatrzymuje wprowadzanie. Funkcja scanf pomija znaki dosłowne.

Ogólnie specyfikacja formatu wejściowego to:

%[*] [szerokość] [modyfikatory] typ

Znak '*' oznacza przerwę podczas wprowadzania pola zdefiniowanego przez tę specyfikację;

- 'szerokość' określa maksymalną liczbę znaków wprowadzanych przez tę specyfikację;

Typ może przyjmować następujące wartości:

c to tablica znaków,

s – ciąg znaków, ciągi są oddzielone pustymi znakami,

d jest liczbą całkowitą ze znakiem przy 10 s/s,

i jest liczbą całkowitą ze znakiem, system liczbowy opiera się na pierwszych dwóch cyfrach,

u jest liczbą całkowitą bez znaku w 10 s/s,

o jest liczbą całkowitą bez znaku w 8 s/s,

x, X to liczba całkowita bez znaku w 16 s/s,

e, E, f, g, G - liczba zmiennoprzecinkowa,

p jest wskaźnikiem do wskaźnika,

n jest wskaźnikiem do liczby całkowitej,

[…] to tablica zeskanowanych znaków, na przykład .

W tym drugim przypadku ze strumienia wejściowego zostaną wprowadzone tylko znaki ujęte w nawiasy kwadratowe. Jeśli pierwszym znakiem w nawiasach kwadratowych jest '^', to wprowadzane są tylko te znaki, które nie są zawarte w tablicy. Zakres znaków w tablicy jest określony za pomocą znaku „-”. Podczas wprowadzania znaków wprowadzane są również początkowe puste znaki i końcowy bajt null ciągu.

Modyfikatory mogą przyjmować następujące wartości:

h jest krótką liczbą całkowitą,

l, L - długa liczba całkowita lub zmiennoprzecinkowa,

i są używane tylko do liczb całkowitych lub zmiennoprzecinkowych.

Poniższy przykład przedstawia przypadki użycia funkcji scanf. Zauważ, że specyfikator formatu jest poprzedzony spacją przed wprowadzeniem liczby zmiennoprzecinkowej.

#włączać

printf("Wprowadź liczbę całkowitą: ");

scanf("%d", &n);

printf("Wpisz podwójne: ");

scanf(" %lf", &d);

printf("Wprowadź znak: ");

scanf(" %c" &c);

printf("Wprowadź ciąg: ");

scanf("%s", &s);

Zauważ, że w tym programie inicjowana jest liczba zmiennoprzecinkowa. Odbywa się to, aby kompilator zawierał bibliotekę obsługującą pracę z liczbami zmiennoprzecinkowymi. Jeśli nie zostanie to zrobione, podczas wprowadzania liczby zmiennoprzecinkowej wystąpi błąd w czasie wykonywania.

Aby sformatować dane wyjściowe do konsoli, użyj funkcji

int printf (const char *format, ...);

który zwraca liczbę jednostek wyjściowych w przypadku sukcesu i EOF w przypadku niepowodzenia. Parametr format to ciąg formatu, który zawiera specyfikacje formatu wyjściowego. Liczba i typy argumentów występujących po ciągu formatu muszą być zgodne z liczbą i typami specyfikacji formatu wyjściowego podanych w ciągu formatu. Ogólnie specyfikacja formatu wyjściowego to:

%[flagi] [szerokość] [.precision] [modyfikatory] typ

- „flagi” to różne symbole określające format wyjściowy;

- 'szerokość' określa minimalną liczbę znaków wyprowadzanych przez tę specyfikację;

- ‘.precision’ określa maksymalną liczbę znaków do wyprowadzenia;

- „modyfikatory” określają rodzaj argumentów;

- 'typ' określa typ argumentu.

Do drukowania liczb całkowitych ze znakiem używany jest następujący format wyjściowy:

%[-] [+ | spacja] [szerokość] [l] d

- – wyrównanie do lewej, domyślnie – do prawej;

+ - wyświetlany jest znak '+', należy zwrócić uwagę, że dla liczb ujemnych zawsze wyświetlany jest znak '-';

„spacja” – spacja jest wyświetlana na pozycji znaku;

d to typ danych int.

Do wyprowadzania liczb całkowitych bez znaku używany jest następujący format wyjściowy:

%[-] [#] [szerokość] [l]

# - wyświetla inicjał 0 dla liczb z 8 c/c lub inicjał 0x lub 0X dla liczb z 16 c/c,

l – modyfikator typu danych long;

u jest liczbą całkowitą w 10c/c,

o jest liczbą całkowitą w 8 c/c,

x, X jest liczbą całkowitą w 16 c/c.

Do wyświetlania liczb zmiennoprzecinkowych używany jest następujący format wyjściowy:

%[-] [+ | spacja] [szerokość] [.precyzja]

„precyzja” odnosi się do liczby cyfr po przecinku dla formatów f, e i E lub liczby cyfr znaczących dla formatów g i G. Liczby są zaokrąglane. Wartość domyślna to sześć cyfr dziesiętnych dokładności;

f jest liczbą stałoprzecinkową,

e to liczba w formie wykładniczej, wykładnik jest oznaczony literą „e”,

E to liczba w formie wykładniczej, wykładnik jest oznaczony literą „E”,

g to najkrótszy z formatów f lub g,

G to najkrótszy z formatów f lub G.

printf ("n = %d\n f = %f\n e = %e\n E = %E\n f = %.2f", -123, 12.34, 12.34, 12.34, 12.34);

// drukuje: n = 123 f = 12.340000 e = 1.234000e+001 E = 1.234000E+001 f = 12.34

1.4. Formatowanie ciągów.

Istnieją warianty funkcji scanf i printf przeznaczone do formatowania łańcuchów i nazywane odpowiednio sscanf i sprintf.

int sscanf (const char *str, const char *format, ...);

odczytuje dane z ciągu określonego przez parametr str zgodnie z ciągiem formatu określonym przez parametr format. Zwraca ilość danych odczytanych w przypadku sukcesu, EOF w przypadku niepowodzenia. Na przykład,

#włączać

char str = "a 10 1.2 String Brak danych wejściowych";

sscanf(str, "%c %d %lf %s", &c, &n, &d, s);

printf("%c\n", c); // drukuje: a

printf("%d\n", n); // wydruki: 10

printf("%f\n", d); // wydruki: 1.200000

printf("%s\n", s); // drukuje: String

int sprintf (char *bufor, const char *format, ...);

formatuje ciąg zgodnie z formatem określonym przez parametr format i zapisuje wynik w tablicy znaków bufora. Funkcja zwraca liczbę znaków zapisanych w tablicy znaków bufora, z wyłączeniem kończącego bajtu null. Na przykład,

#włączać

char str = "c = %c, n = %d, d = %f, s = %s";

char s = "To jest ciąg.";

sprintf(bufor, str, c, n, d, s);

printf("%s\n", bufor); // drukuje: c = c, n = 10, d = 1.200000, s = To jest ciąg

1.5. Konwertuj ciągi na dane liczbowe.

Prototypy funkcji konwersji łańcuchów na dane liczbowe podane są w pliku nagłówkowym stdlib.h, który musi być zawarty w programie.

Aby przekonwertować ciąg na liczbę całkowitą, użyj funkcji

int atoi (const char *str);

char *str = "-123";

n = atoi(str); // n = -123

Aby przekonwertować ciąg na długą liczbę całkowitą, użyj funkcji

long int atol (const char *str);

która, jeśli się powiedzie, zwraca liczbę całkowitą, na którą został przekonwertowany ciąg str, a 0, jeśli się nie powiedzie. Na przykład

char *str = "-123";

n = atol(str); // n = -123

Aby przekonwertować łańcuch na podwójny, użyj funkcji

podwójny atof (const char *str);

która, jeśli się powiedzie, zwraca liczbę zmiennoprzecinkową typu double, na którą konwertowany jest ciąg znaków, a w przypadku niepowodzenia 0. Na przykład

znak *str = "-123.321";

n = atof(str); // n = -123,321

Poniższe funkcje wykonują podobne działania do atoi, atol, atof, ale zapewniają większą funkcjonalność.

long int strtol (const char *str, char **endptr, int base);

konwertuje łańcuch str na długi int, który zwraca. Parametry tej funkcji mają następujący cel.

Jeśli argumentem podstawowym jest 0, konwersja zależy od pierwszych dwóch znaków ciągu:

Jeżeli pierwszym znakiem jest cyfra od 1 do 9, to zakłada się, że liczba jest reprezentowana w 10 c/c;

Jeżeli pierwszym znakiem jest liczba 0, a drugim znakiem jest liczba od 1 do 7, to zakłada się, że liczba jest reprezentowana w 8 c/c;

Jeśli pierwszym znakiem jest 0, a drugim znakiem „X” lub „x”, zakłada się, że liczba jest reprezentowana w postaci 16 c/c.

Jeśli argumentem podstawowym jest liczba od 2 do 36, to ta wartość jest traktowana jako podstawa systemu liczbowego, a każdy znak wykraczający poza ten system zatrzymuje konwersję. Systemy liczbowe o podstawie od 11 do 36 używają symboli „A” do „Z” lub „a” do „z” do reprezentowania cyfr.

Wartość argumentu endptr jest ustawiana przez funkcję strtol. Ta wartość zawiera wskaźnik do znaku, który zatrzymał konwersję str. Funkcja strtol zwraca przekonwertowaną liczbę w przypadku sukcesu i 0 w przypadku niepowodzenia.

n = strtol("12a", &p, 0);

printf("n = %ld, %stop = %c, n, *p); // n = 12, stop = a

n = strtol("012b", &p, 0);

printf("n = %ld, %stop = %c, n, *p); // n = 10, stop = b

n = strtol("0x12z", &p, 0);

printf("n = %ld, %stop = %c, n, *p); // n = 18, stop = z

n = strtol("01117", &p, 0);

printf("n = %ld, %stop = %c, n, *p); // n = 7, stop = 7

unsigned long int strtol (const char *str, char **endptr, int base);

działa podobnie do funkcji strtol, ale konwertuje znakową reprezentację liczby na długi int bez znaku.

double strtod (const char *str, char **endptr);

konwertuje symboliczną reprezentację liczby na podwójną.

Wszystkie funkcje wymienione w tym akapicie przestają działać, gdy napotkają pierwszy znak, który nie pasuje do formatu danej liczby.

Ponadto, jeśli wartość znakowa liczby przekracza zakres dopuszczalnych wartości dla odpowiedniego typu danych, to funkcje atof, strtol, strtoul, strtod ustawiają wartość zmiennej errno na ERANGE. Zmienna errno i stała ERANGE są zdefiniowane w pliku nagłówkowym math.h. Funkcje atof i strtod zwracają HUGE_VAL, funkcja strtol zwraca LONG_MAX lub LONG_MIN, a funkcja strtoul zwraca ULONG_MAX.

Do konwersji danych numerycznych na ciągi znaków można użyć niestandardowych funkcji itoa, ltoa, utoa, ecvt, fcvt i gcvt. Ale do tych celów lepiej jest użyć standardowej funkcji sprintf.

1.6. Standardowe funkcje do pracy z ciągami.

W tej sekcji omówione zostaną funkcje do pracy z łańcuchami, których prototypy są opisane w pliku nagłówkowym string.h.

1. Porównanie strun. Funkcje strcmp i strncmp służą do porównywania ciągów.

int strcmp (const char *str1, const char *str2);

porównuje ciągi str1, str2 leksykograficznie i zwraca -1, 0 lub 1, jeśli str1 jest odpowiednio mniejsze, równe lub większe niż str2.

int strncmp (const char *str1, const char *str2, size_t n);

leksykograficznie porównuje co najwyżej pierwsze n znaków z łańcuchów str1 i str2. Funkcja zwraca -1, 0 lub 1, jeśli pierwszych n znaków słowa str1 jest odpowiednio mniejszych, równych lub większych od pierwszych n znaków słowa.

// przykład porównania ciągów

#włączać

#włączać

znak str1 = "aa bb";

znak str2 = "aa aa";

znak str3 = "aa bb cc";

printf("%d\n", strcmp(str1, str3)); // wydruki: -1

printf("%d\n", strcmp(str1, str1)); // wydruki: -0

printf("%d\n", strcmp(str1, str2)); // wydruki: 1

printf("%d\n", strncmp(str1, str3, 5)); // wydruki: 0

2. Kopiowanie linii. Funkcje strcpy i strncpy służą do kopiowania łańcuchów.

char *strcpy (char *str1, const char *str2);

kopiuje ciąg str2 do ciągu str1. Ciąg str2 jest kopiowany w całości, łącznie z kończącym bajtem null. Funkcja zwraca wskaźnik do str1. Jeśli linie zachodzą na siebie, wynik jest nieprzewidywalny.

char *strncpy (char *str1, const char *str2, size_t n);

kopiuje n znaków z łańcucha str2 do łańcucha str1. Jeśli ciąg str2 zawiera mniej niż n znaków, ostatni bajt zerowy jest kopiowany tyle razy, ile potrzeba, aby rozszerzyć ciąg str2 do n znaków. Funkcja zwraca wskaźnik do ciągu str1.

char str2 = "Kopiuj ciąg.";

strcpy(str1, str2);

printf(str1); // drukuje: Kopiuj ciąg.

4. Łączenie ciągów. Funkcje strcat i strncat służą do łączenia ciągów w jeden ciąg.

char* strcat (char *str1, const char *str2);

dołącza ciąg str2 do ciągu str1, z wymazanym końcowym bajtem null ciągu str1. Funkcja zwraca wskaźnik do ciągu str1.

char* strncat (char *str1, const char *str2, size_t n);

łączy n znaków z łańcucha str2 z łańcuchem str1, kasując kończący bajt null str1. Funkcja zwraca wskaźnik do ciągu str1. jeśli długość łańcucha str2 jest mniejsza niż n, dołączane są tylko znaki zawarte w łańcuchu str2. Po konkatenacji ciągów do str1 zawsze dodawany jest bajt null. Funkcja zwraca wskaźnik do ciągu str1.

#włączać

#włączać

znak str1 = "ciąg";

char str2 = "katenacja";

char str3 = "Tak Nie";

strcat(str1, str2);

printf("%s\n", str1); // wypisuje: katationacja ciągów

strncat(str1, str3, 3);

printf("%s\n", str1); // drukuje: katationacja ciągów Tak

5. Wyszukaj znak w ciągu. Funkcje strchr, strrchr, strspn, strcspn i strpbrk służą do wyszukiwania znaku w ciągu.

char* strchr (const char *str, int c);

wyszukuje pierwsze wystąpienie znaku określonego przez parametr c w ciągu str. W przypadku powodzenia funkcja zwraca wskaźnik do pierwszego znalezionego znaku, a w przypadku niepowodzenia wartość NULL.

char* strrchr (const char *str, int c);

wyszukuje ostatnie wystąpienie znaku określonego przez parametr c w ciągu str. W przypadku powodzenia funkcja zwraca wskaźnik do ostatniego znalezionego znaku, a w przypadku niepowodzenia wartość NULL.

#włączać

#włączać

znak str = "wyszukiwanie znaków";

printf("%s\n", strchr(str, "r")); // wypisuje: r szukaj

printf("%s\n", strrchr(str, "r")); // wydruki: rch

size_t strspn (const char *str1, const char *str2);

zwraca indeks pierwszego znaku w str1, którego nie ma w str2.

size_t strcspn (const char *str1, const char *str2);

zwraca indeks pierwszego znaku w str1, który znajduje się w str2.

znak znak = "123 abc";

printf("n = %d\n", strspn(str, "321"); // drukuje: n = 3

printf ("n = %d\n", strcspn (str, "cba"); // drukuje: n = 4

char* strpbrk (const char *str1, const char *str2);

znajduje pierwszy znak w str1, który jest równy jednemu ze znaków w str2. W przypadku powodzenia funkcja zwraca wskaźnik do tego znaku, a w przypadku niepowodzenia wartość NULL.

znak znak = "123 abc";

printf("%s\n", strpbrk(str, "bca")); // wydruki: abc

6. Porównanie strun. Funkcja strstr służy do porównywania ciągów.

char* strstr (const char *str1, const char *str2);

znajduje pierwsze wystąpienie ciągu str2 (bez końcowego bajtu null) w ciągu str1. W przypadku powodzenia funkcja zwraca wskaźnik do znalezionego podciągu, a w przypadku niepowodzenia wartość NULL. Jeśli wskaźnik str1 wskazuje na ciąg o zerowej długości, funkcja zwraca wskaźnik str1.

znak znak = "123 abc 456;

printf("%s\n", strstr(str, "abc"); // print: abc 456

7. Parsowanie ciągu na tokeny. Funkcja strtok służy do przetwarzania ciągu na tokeny.

char* strtok (char *str1, const char *str2);

zwraca wskaźnik do następnego tokena (słowa) w ciągu str1, gdzie separatory tokenów są znakami z ciągu str2. Jeśli tokeny się skończyły, funkcja zwraca NULL. Przy pierwszym wywołaniu funkcji strtok parametr str1 musi wskazywać ciąg, który jest analizowany na tokeny, a przy kolejnych wywołaniach ten parametr musi mieć wartość NULL. Po znalezieniu tokenu funkcja strtok zapisuje bajt null po tym tokenie w miejsce ogranicznika.

#włączać

#włączać

znak str = "12 34 ab cd";

p = strtok(str, " ");

printf("%s\n",p); // wyświetla wartości w kolumnie: 12 34 ab cd

p = strtok(NULL, " ");

8. Określanie długości sznurka. Funkcja strlen służy do określenia długości ciągu.

size_t strlen(const char *str);

zwraca długość ciągu, ignorując ostatni bajt null. Na przykład,

znak znak = "123";

printf("len = %d\n",strlen(str)); // wydruki: len = 3

1.7. Funkcje do pracy z pamięcią.

Plik nagłówkowy string.h opisuje również funkcje do pracy z blokami pamięci, które są podobne do odpowiednich funkcji do pracy z łańcuchami.

void* memchr(const void *str, int c, size_t n);

wyszukuje pierwsze wystąpienie znaku określonego przez c w n bajtach str.

int memcmp(const void *str1, const void *str2, size_t n);

porównuje pierwsze n bajtów str1 i str2.

void* memcpy(const void *str1, const void *str2, size_t n);

kopiuje pierwsze n bajtów z łańcucha str1 do łańcucha str2.

void* memmove(const void *str1, const void *str2, size_t n);

kopiuje pierwsze n bajtów z str1 do str2, upewniając się, że nakładające się ciągi są obsługiwane poprawnie.

void* memset(const void *str, int c, size_t n);

kopiuje znak określony przez c do pierwszych n bajtów str.