Łańcuchy znaków – string w C#
Poznasz najważniejsze metody pracy z tekstem: wyszukiwanie, wycinanie, łączenie, dzielenie i formatowanie stringów.
Czym jest string?
String (łańcuch znaków) 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); // string to alias dla System.String String tekst2 = "To samo co string";
Kluczowe informacje
| Cecha | Opis |
|---|---|
| Alias | string = System.String |
| Niemutowalny | Nie można zmieniać zawartości – każda „zmiana” tworzy nowy obiekt |
| Indeksowanie | Można traktować jak tablicę znaków (dostęp przez [indeks]) |
| Cudzysłów | Tekst w podwójnych cudzysłowach: "tekst" |
Kiedy „zmieniasz” string, np. tekst = tekst.ToUpper(), tak naprawdę tworzysz nowy obiekt w pamięci. Oryginalny string pozostaje niezmieniony (lub jest usuwany przez garbage collector).
Dostęp do pojedynczych znaków
String można traktować jak tablicę znaków char. Dostęp przez indeks w nawiasach kwadratowych.
string nazwa = "C# jest super"; // Dostęp do znaków przez indeks (od 0!) char pierwszyZnak = nazwa[0]; // 'C' char trzeci = nazwa[2]; // ' ' (spacja) // Ostatni znak char ostatni = nazwa[nazwa.Length - 1]; // 'r' // Właściwość Length – liczba znaków Console.WriteLine($"Długość: {nazwa.Length}"); // 13 // Iteracja przez wszystkie znaki foreach (char c in nazwa) { Console.Write($"[{c}]"); } // Wynik: [C][#][ ][j][e][s][t][ ][s][u][p][e][r]
nazwa[0] = 'D'; → BŁĄD KOMPILACJI!
String jest niemutowalny – nie można zmieniać pojedynczych znaków przez przypisanie.
| Składnia | Opis | Przykład |
|---|---|---|
tekst[i] | Znak na pozycji i | "ABC"[0] → 'A' |
tekst.Length | Liczba znaków | "ABC".Length → 3 |
tekst[tekst.Length-1] | Ostatni znak | "ABC"[2] → 'C' |
Sprawdzanie i czyszczenie tekstu
Pusty string i null
// Różne sposoby utworzenia pustego stringa string pusty1 = ""; string pusty2 = string.Empty; // Preferowane! // Sprawdzanie czy string jest pusty lub null string tekst = ""; if (string.IsNullOrEmpty(tekst)) { Console.WriteLine("String jest pusty lub null"); } // Sprawdza też białe znaki (spacje, taby) string spacje = " "; if (string.IsNullOrWhiteSpace(spacje)) { Console.WriteLine("String jest pusty, null lub same spacje"); }
Usuwanie białych znaków (Trim)
string zSpacjami = " Witaj świecie! "; Console.WriteLine($"Oryginalny: '[{zSpacjami}]'"); Console.WriteLine($"Trim(): '[{zSpacjami.Trim()}]'"); Console.WriteLine($"TrimStart(): '[{zSpacjami.TrimStart()}]'"); Console.WriteLine($"TrimEnd(): '[{zSpacjami.TrimEnd()}]'"); // Wynik: // Oryginalny: '[ Witaj świecie! ]' // Trim(): '[Witaj świecie!]' // TrimStart(): '[Witaj świecie! ]' // TrimEnd(): '[ Witaj świecie!]'
Zmiana wielkości liter
string tekst = "Programowanie w C#"; Console.WriteLine(tekst.ToUpper()); // PROGRAMOWANIE W C# Console.WriteLine(tekst.ToLower()); // programowanie w c# // Przydatne przy porównywaniu (ignorowanie wielkości liter) string input = "ANNA"; if (input.ToLower() == "anna") { Console.WriteLine("Imiona są takie same!"); }
| Metoda | Opis |
|---|---|
string.IsNullOrEmpty(s) | Sprawdza czy null lub "" |
string.IsNullOrWhiteSpace(s) | Sprawdza też białe znaki |
s.Trim() | Usuwa spacje z początku i końca |
s.TrimStart() | Usuwa spacje tylko z początku |
s.TrimEnd() | Usuwa spacje tylko z końca |
s.ToUpper() | Zamienia na WIELKIE litery |
s.ToLower() | Zamienia na małe litery |
Wyszukiwanie w tekście
string email = "student@technikum.edu.pl"; // Sprawdzanie zawartości (zwraca true/false) Console.WriteLine(email.Contains("@")); // true Console.WriteLine(email.StartsWith("student")); // true Console.WriteLine(email.EndsWith(".pl")); // true // Znajdowanie pozycji (zwraca indeks lub -1) int pozycja = email.IndexOf('@'); Console.WriteLine($"Pozycja @: {pozycja}"); // 7 // Sprawdzanie czy NIE znaleziono if (email.IndexOf('$') == -1) { Console.WriteLine("Nie zawiera znaku $"); } // LastIndexOf – ostatnie wystąpienie int ostatniaPozycja = email.LastIndexOf('.'); Console.WriteLine($"Ostatnia kropka: {ostatniaPozycja}"); // 21
| Metoda | Zwraca | Opis |
|---|---|---|
Contains("tekst") | bool | Czy zawiera podany fragment? |
StartsWith("tekst") | bool | Czy zaczyna się od…? |
EndsWith("tekst") | bool | Czy kończy się na…? |
IndexOf("tekst") | int | Pozycja pierwszego wystąpienia (-1 jeśli brak) |
LastIndexOf("tekst") | int | Pozycja ostatniego wystąpienia |
Jeśli szukany tekst nie został znaleziony, IndexOf() zwraca -1. Zawsze sprawdzaj ten przypadek!
Wycinanie fragmentów (Substring)
Metoda Substring() pozwala wyciąć fragment tekstu.
string kod = "PL-12345-ABC"; Console.WriteLine($"Oryginalny: {kod}"); // Substring(startIndex, length) – wycina "length" znaków od pozycji "startIndex" string kraj = kod.Substring(0, 2); // "PL" string numer = kod.Substring(3, 5); // "12345" // Substring(startIndex) – od pozycji do końca string litery = kod.Substring(9); // "ABC" Console.WriteLine($"Kraj: {kraj}"); Console.WriteLine($"Numer: {numer}"); Console.WriteLine($"Litery: {litery}");
"PL-12345-ABC"
Indeksy: 0 1 2 3 4 5 6 7 8 9 10 11
Substring(0, 2) → od pozycji 0, weź 2 znaki → "PL"
Substring(3, 5) → od pozycji 3, weź 5 znaków → "12345"
Substring(9) → od pozycji 9 do końca → "ABC"
| Składnia | Opis |
|---|---|
Substring(startIndex) | Od pozycji startIndex do końca |
Substring(startIndex, length) | Od pozycji startIndex, długość length |
Jeśli startIndex lub length wykracza poza długość stringa, program rzuci ArgumentOutOfRangeException!
Łączenie stringów
Operator + (proste łączenie)
string imie = "Anna"; string nazwisko = "Kowalska"; // Operator + string pelne = imie + " " + nazwisko; Console.WriteLine(pelne); // "Anna Kowalska" // Interpolacja (preferowana!) string pelne2 = $"{imie} {nazwisko}"; Console.WriteLine(pelne2); // "Anna Kowalska"
string.Join() – łączenie z separatorem
// Łączenie tablicy w jeden string string[] przedmioty = { "Matematyka", "Informatyka", "Fizyka" }; string lista = string.Join(", ", przedmioty); Console.WriteLine(lista); // "Matematyka, Informatyka, Fizyka" // Działa też z liczbami! int[] oceny = { 5, 4, 4, 3, 5 }; string listaOcen = string.Join(" - ", oceny); Console.WriteLine(listaOcen); // "5 - 4 - 4 - 3 - 5"
StringBuilder – dla wielu łączeń
using System.Text; // StringBuilder jest wydajniejszy dla wielu łączeń StringBuilder sb = new StringBuilder(); sb.Append("Imię: "); sb.Append("Anna"); sb.AppendLine(); // Dodaje nową linię sb.Append("Wiek: 20"); string wynik = sb.ToString(); Console.WriteLine(wynik);
Gdy łączysz stringi w pętli (np. 100+ razy). Każde + tworzy nowy obiekt w pamięci, a StringBuilder modyfikuje jeden obiekt.
Dzielenie tekstu (Split)
Metoda Split() dzieli string na tablicę stringów według separatora.
// Dzielenie po przecinku string dane = "Anna,Kowalska,20,Warszawa"; string[] elementy = dane.Split(','); Console.WriteLine($"Imię: {elementy[0]}"); // Anna Console.WriteLine($"Nazwisko: {elementy[1]}"); // Kowalska Console.WriteLine($"Wiek: {elementy[2]}"); // 20 Console.WriteLine($"Miasto: {elementy[3]}"); // Warszawa // Dzielenie po spacjach string zdanie = "To jest przykładowe zdanie"; string[] slowa = zdanie.Split(' '); Console.WriteLine($"Liczba słów: {slowa.Length}"); // 4
Split z wieloma separatorami
string tekst = "jeden;dwa,trzy cztery"; // Dzielenie po wielu separatorach char[] separatory = { ';', ',', ' ' }; string[] czesci = tekst.Split(separatory); foreach (string c in czesci) { Console.WriteLine(c); } // jeden // dwa // trzy // cztery // Usuwanie pustych elementów string tekst2 = "a,,b, ,c"; string[] bez = tekst2.Split(',', StringSplitOptions.RemoveEmptyEntries); // Wynik: ["a", "b", " ", "c"] (puste usunięte, ale spacje nie)
Zamiana tekstu (Replace)
string tekst = "C++ jest trudny, ale C++ jest potężny"; // Zamiana wszystkich wystąpień string nowy = tekst.Replace("C++", "C#"); Console.WriteLine(nowy); // "C# jest trudny, ale C# jest potężny" // Usuwanie znaków (zamiana na pusty string) string zSpacjami = "t e k s t"; string bezSpacji = zSpacjami.Replace(" ", ""); Console.WriteLine(bezSpacji); // "tekst" // Zamiana pojedynczego znaku string path = "C:\\Users\\Jan\\Dokumenty"; string unix = path.Replace('\\', '/'); Console.WriteLine(unix); // "C:/Users/Jan/Dokumenty"
Metoda Replace() zamienia wszystkie wystąpienia podanego tekstu, nie tylko pierwsze. Oryginalny string pozostaje niezmieniony – zwracany jest nowy string.
Formatowanie stringów
Interpolacja (preferowana metoda)
string imie = "Anna"; int wiek = 20; double srednia = 4.756; DateTime teraz = DateTime.Now; // Podstawowa interpolacja string info = $"Cześć {imie}! Masz {wiek} lat."; Console.WriteLine(info); // Formatowanie liczb Console.WriteLine($"Średnia: {srednia:F2}"); // 4,76 Console.WriteLine($"Procent: {srednia:P0}"); // 476% Console.WriteLine($"Waluta: {srednia:C}"); // 4,76 zł // Formatowanie dat Console.WriteLine($"Data: {teraz:dd.MM.yyyy}"); // 24.09.2025 Console.WriteLine($"Czas: {teraz:HH:mm:ss}"); // 14:30:25 Console.WriteLine($"Pełna: {teraz:dddd, d MMMM}"); // środa, 24 września
Przydatne formaty
| Format | Opis | Przykład |
|---|---|---|
:F2 | 2 miejsca po przecinku | 3.14159 → 3.14 |
:N0 | Bez miejsc, z separatorami | 1234567 → 1 234 567 |
:C | Waluta | 99.9 → 99,90 zł |
:P0 | Procent | 0.15 → 15% |
:dd.MM.yyyy | Data | 24.09.2025 |
:HH:mm | Czas 24h | 14:30 |
Częste błędy i pułapki
❌ Błąd 1: Próba zmiany znaku
❌ Źle
tekst[0] = 'h';
Błąd kompilacji! String niemutowalny.
✅ Dobrze
tekst = 'h' + tekst.Substring(1);
Tworzymy nowy string.
❌ Błąd 2: Porównywanie bez wielkości liter
❌ Niebezpieczne
if (input == "Anna")
„ANNA” ≠ „Anna”!
✅ Bezpieczne
if (input.ToLower() == "anna")
Lub: string.Equals(input, "Anna", StringComparison.OrdinalIgnoreCase)
❌ Błąd 3: Łączenie w pętli
❌ Nieefektywne
for (...) wynik += i;
Tworzy setki obiektów!
✅ Efektywne
StringBuilder sb;
for (...) sb.Append(i);
❌ Błąd 4: Brak sprawdzenia null
string tekst = null; // ❌ Rzuci NullReferenceException! // int dlugosc = tekst.Length; // ✅ Bezpieczne sprawdzenie if (!string.IsNullOrEmpty(tekst)) { int dlugosc = tekst.Length; }
Podsumowanie
Najważniejsze metody string
| Kategoria | Metody |
|---|---|
| Sprawdzanie | Contains(), StartsWith(), EndsWith(), IsNullOrEmpty() |
| Czyszczenie | Trim(), TrimStart(), TrimEnd() |
| Wielkość liter | ToUpper(), ToLower() |
| Wyszukiwanie | IndexOf(), LastIndexOf() |
| Wycinanie | Substring() |
| Zamiana | Replace() |
| Dzielenie/łączenie | Split(), string.Join() |
1. String jest niemutowalny – każda „zmiana” tworzy nowy obiekt
2. Używaj interpolacji $"" do formatowania
3. StringBuilder dla wielu operacji łączenia w pętli
4. Zawsze sprawdzaj wielkość liter przy porównaniach
5. Używaj IsNullOrEmpty() przed operacjami na stringach
Zadania praktyczne
📝 Zadanie 1: Walidator hasła
Napisz funkcję CzyHasloPoprawne(string haslo), która sprawdza:
- Minimum 8 znaków
- Zawiera wielką literę
- Zawiera małą literę
- Zawiera cyfrę
Zwraca true jeśli wszystkie warunki spełnione.
💡 Podpowiedź: Iteruj przez foreach (char c in haslo)
📝 Zadanie 2: Generator inicjałów
Napisz funkcję DajInicjaly(string imieNazwisko), która:
- Przyjmuje „Jan Kowalski” i zwraca „J.K.”
- Obsługuje też więcej słów: „Jan Maria Kowalski” → „J.M.K.”
💡 Podpowiedź: Użyj Split(' ') i slowo[0]
📝 Zadanie 3: Walidator emaila
Napisz funkcję CzyEmailPoprawny(string email), która sprawdza:
- Zawiera dokładnie jeden znak
@ - Przed
@jest minimum 1 znak - Po
@jest minimum 3 znaki - Kończy się na
.pl,.comlub.edu
⭐ Zadanie 4: Cenzura tekstu
Napisz program, który:
- Ma listę „zabronionych” słów
- Zamienia je na gwiazdki (tyle gwiazdek ile liter)
- Np. „brzydkie” (8 liter) → „********”
💡 Podpowiedź: new string('*', slowo.Length)
⭐⭐ Zadanie 5: Parser CSV
Napisz program, który:
- Wczytuje dane CSV: „Imie,Nazwisko,Wiek”
- Konwertuje na format: „Imię Nazwisko (wiek lat)”
- Oblicza średni wiek wszystkich osób
- Znajduje najstarszą i najmłodszą osobę
Przykład: „Anna,Kowalska,20” → „Anna Kowalska (20 lat)”