Wprowadzenie – czym jest string?
Łańcuch znaków (string) to ciąg pojedynczych znaków reprezentujący tekst. W C# jest to typ referencyjny, ale zachowuje się często jak typ wartościowy.
string tekst = "Witaj świecie!";
Console.WriteLine(tekst);Kluczowe informacje:
stringto alias dlaSystem.String- Jest niemutowalny – nie można zmieniać jego zawartości
- Każda „zmiana” tworzy nowy obiekt string w pamięci
- Można traktować jak tablicę znaków (dostęp przez indeks)
Dostęp do pojedynczych znaków
string nazwa = "C# jest super";
char pierwszyZnak = nazwa[0]; // 'C'
char ostatniZnak = nazwa[nazwa.Length - 1]; // 'r'
Console.WriteLine($"Pierwszy znak: {pierwszyZnak}");
Console.WriteLine($"Ostatni znak: {ostatniZnak}");
Console.WriteLine($"Długość tekstu: {nazwa.Length}");
// UWAGA: Nie można zmieniać znaków przez przypisanie!
// nazwa[0] = 'D'; // ❌ BŁĄD! String jest niemutowalnyWyjaśnienie funkcji:
tekst[indeks]– dostęp do znaku na danej pozycji (indeks od 0)tekst.Length– właściwość zwracająca liczbę znaków w stringu- Indeksowanie działa jak w tablicach (pierwszy element ma indeks 0)
2. Podstawowe właściwości i metody string
2.1 string.Empty – pusty string
// Różne sposoby utworzenia pustego stringu
string pusty1 = "";
string pusty2 = string.Empty;
// Sprawdzanie czy string jest pusty
if (tekst == string.Empty)
{
Console.WriteLine("String jest pusty");
}
// Lepszy sposób sprawdzania
if (string.IsNullOrEmpty(tekst))
{
Console.WriteLine("String jest pusty lub null");
}Wyjaśnienie funkcji:
string.Empty– reprezentuje pusty string (preferowane nad „”)string.IsNullOrEmpty(tekst)– sprawdza czy string jest null lub pustystring.IsNullOrWhiteSpace(tekst)– dodatkowo sprawdza czy zawiera tylko białe znaki
2.2 Usuwanie białych znaków
string zSpacjami = " Witaj świecie! ";
Console.WriteLine($"Oryginalny: '[{zSpacjami}]'");
Console.WriteLine($"Trim(): '[{zSpacjami.Trim()}]'");
Console.WriteLine($"TrimStart(): '[{zSpacjami.TrimStart()}]'");
Console.WriteLine($"TrimEnd(): '[{zSpacjami.TrimEnd()}]'");Wyjaśnienie funkcji:
Trim()– usuwa białe znaki (spacje, taby, nowe linie) z początku i końcaTrimStart()– usuwa białe znaki tylko z początkuTrimEnd()– usuwa białe znaki tylko z końca- Białe znaki to: spacja, tab (\t), nowa linia (\n, \r\n)
2.3 Zmiana wielkości liter
string tekst = "Programowanie w C#";
Console.WriteLine($"Oryginał: {tekst}");
Console.WriteLine($"Wielkie litery: {tekst.ToUpper()}");
Console.WriteLine($"Małe litery: {tekst.ToLower()}");
// Przydatne przy porównywaniu (ignorowanie wielkości liter)
string input = "ANNA";
if (input.ToLower() == "anna")
{
Console.WriteLine("Imiona są takie same (ignorując wielkość liter)");
}Wyjaśnienie funkcji:
ToUpper()– konwertuje wszystkie znaki na wielkie literyToLower()– konwertuje wszystkie znaki na małe litery- Przydatne przy porównywaniu tekstów bez uwzględniania wielkości liter
- Nie zmienia oryginalnego stringu – tworzy nowy
3. Wyszukiwanie i sprawdzanie zawartości
3.1 Metody sprawdzające
string email = "student@technikum.edu.pl";
// Sprawdzanie zawartości
Console.WriteLine($"Zawiera '@': {email.Contains("@")}"); // true
Console.WriteLine($"Zaczyna się od 'student': {email.StartsWith("student")}"); // true
Console.WriteLine($"Kończy się na '.pl': {email.EndsWith(".pl")}"); // true
// Znajdowanie pozycji
int pozycjaMałpa = email.IndexOf('@');
Console.WriteLine($"Pozycja znaku '@': {pozycjaMałpa}"); // 7
// Sprawdzanie czy znak/tekst nie został znaleziony
if (email.IndexOf('$') == -1)
{
Console.WriteLine("Email nie zawiera znaku '$'");
}Wyjaśnienie funkcji:
Contains(tekst)– sprawdza czy string zawiera podany fragment (zwraca true/false)StartsWith(tekst)– sprawdza czy string zaczyna się od podanego fragmentuEndsWith(tekst)– sprawdza czy string kończy się podanym fragmentemIndexOf(znak/tekst)– zwraca pozycję pierwszego wystąpienia (-1 jeśli nie znaleziono)LastIndexOf(znak/tekst)– zwraca pozycję ostatniego wystąpienia
3.2 Wycinanie fragmentów
string kod = "PL-12345-ABC";
Console.WriteLine($"Oryginalny kod: {kod}");
// Substring - wycięcie fragmentu
string krajKod = kod.Substring(0, 2); // "PL"
string numerKod = kod.Substring(3, 5); // "12345"
string literowKod = kod.Substring(9); // "ABC" (od pozycji 9 do końca)
Console.WriteLine($"Kraj: {krajKod}");
Console.WriteLine($"Numer: {numerKod}");
Console.WriteLine($"Litery: {literowKod}");Wyjaśnienie funkcji:
Substring(startIndex)– zwraca część stringu od pozycji startIndex do końcaSubstring(startIndex, length)– zwraca część stringu o określonej długości- Indeksy liczą się od 0
- Jeśli przekroczymy długość stringu, zostanie rzucony wyjątek
4. Formatowanie łańcuchów znaków
4.1 Interpolacja stringów (najwygodniejsza metoda)
string imie = "Anna";
int wiek = 20;
double srednia = 4.75;
// Podstawowa interpolacja
string info = $"Cześć {imie}! Masz {wiek} lat.";
Console.WriteLine(info);
// Formatowanie liczb
string oceny = $"Twoja średnia to {srednia:F2}"; // F2 = 2 miejsca po przecinku
Console.WriteLine(oceny);
// Formatowanie dat
DateTime teraz = DateTime.Now;
string data = $"Dzisiejsza data: {teraz:dd.MM.yyyy}";
Console.WriteLine(data);Wyjaśnienie funkcji:
$"tekst {zmienna}"– interpolacja stringów ($ przed cudzysłowem){zmienna:format}– formatowanie wartości wewnątrz nawiasów:F2– formatuje liczbę z 2 miejscami po przecinku:dd.MM.yyyy– formatuje datę (dzień.miesiąc.rok):C– formatuje jako walutę,:P– jako procent
4.2 string.Format() – klasyczna metoda
string szablon = "Imię: {0}, Wiek: {1}, Średnia: {2:F1}";
string wynik = string.Format(szablon, "Piotr", 19, 4.33);
Console.WriteLine(wynik); // "Imię: Piotr, Wiek: 19, Średnia: 4.3"Wyjaśnienie funkcji:
string.Format(szablon, arg0, arg1, ...)– formatuje string wg szablonu{0},{1},{2}– miejsca na argumenty (numerowane od 0){2:F1}– argument 2 z formatowaniem do 1 miejsca po przecinku
5. Łączenie i dzielenie stringów
5.1 string.Join() – łączenie z separatorem
// Łączenie tablicy w jeden string
string[] przedmioty = {"Matematyka", "Informatyka", "Fizyka", "Chemia"};
string lista = string.Join(", ", przedmioty);
Console.WriteLine($"Przedmioty: {lista}");
// Wynik: "Przedmioty: Matematyka, Informatyka, Fizyka, Chemia"
// Łączenie liczb
int[] oceny = {5, 4, 4, 3, 5};
string listaOcen = string.Join(" - ", oceny);
Console.WriteLine($"Oceny: {listaOcen}");
// Wynik: "Oceny: 5 - 4 - 4 - 3 - 5"Wyjaśnienie funkcji:
string.Join(separator, kolekcja)– łączy elementy kolekcji używając separatora- Separator to string, który zostanie wstawiony między elementy
- Działa z tablicami, listami i innymi kolekcjami
- Automatycznie konwertuje elementy na stringi
5.2 Operatory łączenia
// Operator + (unikaj dla wielu łączeń!)
string imie = "Anna";
string nazwisko = "Kowalska";
string pelne = imie + " " + nazwisko; // "Anna Kowalska"
// StringBuilder dla wielu operacji łączenia (wydajniejszy)
using System.Text;
StringBuilder sb = new StringBuilder();
sb.Append("Imię: ");
sb.Append(imie);
sb.Append(", Nazwisko: ");
sb.Append(nazwisko);
string wynik = sb.ToString();Wyjaśnienie funkcji:
- Operator
+– łączy stringi, ale tworzy nowy obiekt przy każdej operacji StringBuilder– klasa do wydajnego łączenia wielu stringówsb.Append(tekst)– dodaje tekst do StringBuildersb.ToString()– konwertuje StringBuilder na string
6. Zamiana i zastępowanie
6.1 Replace() – zastępowanie fragmentów
string tekst = "C++ jest trudny, ale C++ jest potężny";
string nowy = tekst.Replace("C++", "C#");
Console.WriteLine(nowy); // "C# jest trudny, ale C# jest potężny"
// Usuwanie znaków (zastąpienie pustym stringiem)
string zSpacjami = "t e k s t";
string bezSpacji = zSpacjami.Replace(" ", "");
Console.WriteLine(bezSpacji); // "tekst"
// Zamiana wielkich na małe (ręcznie)
string tekst2 = "WITAJ";
string maly = tekst2.Replace("W", "w").Replace("I", "i").Replace("T", "t")
.Replace("A", "a").Replace("J", "j");
// Lepiej użyć ToLower()!Wyjaśnienie funkcji:
Replace(staryTekst, nowyTekst)– zamienia wszystkie wystąpienia staryTekst na nowyTekst- Zamienia WSZYSTKIE wystąpienia, nie tylko pierwsze
- Zwraca nowy string (oryginalny pozostaje niezmieniony)
- Można używać do usuwania (zastąpienie pustym stringiem)
7. Najczęstsze błędy i pułapki
7.1 Niemutowalność stringów
// ❌ BŁĄD - próba zmiany znaku
string tekst = "Hello";
// tekst[0] = 'h'; // Błąd kompilacji!
// ✅ PRAWIDŁOWO - tworzenie nowego stringu
string tekst2 = 'h' + tekst.Substring(1); // "hello"7.2 Porównywanie stringów
// ❌ Niebezpieczne - wielkość liter ma znaczenie
if (input == "Anna") { }
// ✅ Bezpieczne porównanie
if (input.ToLower() == "anna") { }
// lub
if (string.Equals(input, "Anna", StringComparison.OrdinalIgnoreCase)) { }7.3 Wydajność przy łączeniu
// ❌ Nieefektywne dla wielu łączeń
string wynik = "";
for (int i = 0; i < 1000; i++)
{
wynik += i.ToString(); // Tworzy 1000 nowych obiektów!
}
// ✅ Efektywne
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++)
{
sb.Append(i);
}
string wynik = sb.ToString();8.Przydatne wzorce formatowania
double liczba = 1234.5678;
DateTime data = DateTime.Now;
Console.WriteLine($"{liczba:F2}"); // 1234.57 (2 miejsca po przecinku)
Console.WriteLine($"{liczba:C}"); // 1 234,57 zł (waluta)
Console.WriteLine($"{liczba:P}"); // 123 456,78% (procent)
Console.WriteLine($"{liczba:N0}"); // 1 235 (liczba całkowita z separatorami)
Console.WriteLine($"{data:dd.MM.yyyy}"); // 24.09.2025
Console.WriteLine($"{data:HH:mm:ss}"); // 14:30:25
Console.WriteLine($"{data:dddd, dd MMMM yyyy}"); // środa, 24 września 20259. Praktyczny przykład – analiza pliku tekstowego
using System;
using System.IO;
using System.Linq;
class AnalizatorTekstu
{
static void Main()
{
string nazwaPliku = "tekst.txt";
// Tworzymy przykładowy plik
if (!File.Exists(nazwaPliku))
{
string przykład = @"Programowanie w C# jest fascynujące!
C# to nowoczesny język programowania.
Dzięki C# możemy tworzyć różne aplikacje.";
File.WriteAllText(nazwaPliku, przykład);
}
// Wczytujemy plik
string zawartość = File.ReadAllText(nazwaPliku);
Console.WriteLine("=== ANALIZA PLIKU ===");
Console.WriteLine($"Zawartość pliku:\n{zawartość}\n");
// Podstawowe statystyki
Console.WriteLine("=== STATYSTYKI ===");
Console.WriteLine($"Liczba znaków: {zawartość.Length}");
Console.WriteLine($"Liczba linii: {zawartość.Split('\n').Length}");
// Analiza słów
string[] słowa = zawartość.Split(new char[] {' ', '\n', '\r', '.', '!', ','},
StringSplitOptions.RemoveEmptyEntries);
Console.WriteLine($"Liczba słów: {słowa.Length}");
// Najczęściej występujące słowo
var grupySlów = słowa.GroupBy(s => s.ToLower())
.OrderByDescending(g => g.Count())
.First();
Console.WriteLine($"Najczęstsze słowo: '{grupySlów.Key}' ({grupySlów.Count()} razy)");
// Statystyki znaków specjalnych
int spacje = zawartość.Count(c => c == ' ');
int literC = zawartość.ToUpper().Count(c => c == 'C');
Console.WriteLine($"Liczba spacji: {spacje}");
Console.WriteLine($"Liczba liter 'C' (bez względu na wielkość): {literC}");
// Sprawdzanie zawartości
Console.WriteLine("\n=== WYSZUKIWANIE ===");
Console.WriteLine($"Zawiera słowo 'programowanie': {zawartość.ToLower().Contains("programowanie")}");
Console.WriteLine($"Zaczyna się od 'Program': {zawartość.StartsWith("Program")}");
// Formatowanie wyniku
string raport = $@"
=== RAPORT ANALIZY ===
Plik: {nazwaPliku}
Data analizy: {DateTime.Now:dd.MM.yyyy HH:mm}
Znaków: {zawartość.Length}
Słów: {słowa.Length}
Linii: {zawartość.Split('\n').Length}
Najczęstsze słowo: {grupySlów.Key}
";
// Zapisanie raportu
File.WriteAllText("raport.txt", raport);
Console.WriteLine("\nRaport zapisano do pliku 'raport.txt'");
}
}Wyjaśnienie nowych funkcji:
Count(warunek)– liczy elementy spełniające warunek (wymaga using System.Linq)GroupBy(funkcja)– grupuje elementy według kluczaOrderByDescending()– sortuje malejącoFirst()– pobiera pierwszy element@"tekst"– verbatim string (wieloliniowy, bez interpretacji znaków specjalnych)
10. Podsumowanie
Najważniejsze metody string:
- Sprawdzanie:
Contains(),StartsWith(),EndsWith(),IsNullOrEmpty() - Manipulacja:
Trim(),ToUpper(),ToLower(),Replace(),Substring() - Wyszukiwanie:
IndexOf(),LastIndexOf() - Formatowanie: interpolacja
$"",string.Format() - Łączenie:
string.Join(),StringBuilderdla wielu operacji - Dzielenie:
Split()(poznane w poprzedniej lekcji)
Kluczowe zasady:
- String jest niemutowalny – każda „zmiana” tworzy nowy obiekt
- Używaj interpolacji
$""do formatowania - StringBuilder do wielu operacji łączenia
- Zawsze sprawdzaj wielkość liter przy porównaniach
- Łącz wiedzę o stringach z operacjami na plikach
11. Praktyczne zadania
Zadanie 1 – Walidator hasła
Napisz program, który:
- Pobiera hasło od użytkownika
- Sprawdza czy hasło ma co najmniej 8 znaków
- Sprawdza czy zawiera wielką literę, małą literę i cyfrę
- Wyświetla wynik walidacji
Zadanie 2 – Generator inicjałów
Napisz program, który:
- Pobiera imię i nazwisko
- Tworzy inicjały (pierwsze litery)
- Formatuje je jako „A.K.” (wielkie litery z kropkami)
Zadanie 3 – Cenzura tekstu
Napisz program, który:
- Wczytuje plik tekstowy
- Zastępuje wybrane słowa gwiazdkami (np. „brzydkie” → „********”)
- Zapisuje ocenzurowany tekst do nowego pliku
- Wyświetla statystykę zmian
Zadanie 4 – Analizator emaili
Napisz program, który:
- Wczytuje plik z adresami email (jeden w linii)
- Sprawdza poprawność każdego adresu (zawiera @ i domenę)
- Grupuje według domen (np. gmail.com, outlook.com)
- Zapisuje raport do pliku
Zadanie 5 – Konwerter formatów
Napisz program, który:
- Wczytuje plik CSV z danymi: „Imię,Nazwisko,Wiek”
- Konwertuje na format: „Imię Nazwisko (wiek lat)”
- Zapisuje do pliku tekstowego
- Dodaje statystyki (średni wiek, najstarszy/najmłodszy)