Typ char w C# – pojedynczy znak

Nauczysz się pracować z pojedynczymi znakami – klasyfikować je, konwertować i wykorzystywać w walidacji danych.

char Unicode IsLetter IsDigit escape sequences
01

Czym jest char?

char to typ wartościowy reprezentujący pojedynczy znak Unicode. W odróżnieniu od string, który może zawierać wiele znaków, char zawsze reprezentuje dokładnie jeden znak.

cs/CharVsString.cs C#
// char – APOSTROF (jeden znak)
char literaA = 'A';
char cyfra5 = '5';
char spacja = ' ';

// string – CUDZYSŁÓW (zero lub więcej znaków)
string tekst = "ABC";

Console.WriteLine($"Char: {literaA}");    // A
Console.WriteLine($"String: {tekst}");   // ABC
Zapamiętaj!

'A' (apostrof) = char (jeden znak)
"A" (cudzysłów) = string (tekst)

Kluczowe różnice char vs string

Właściwośćcharstring
CudzysłowyApostrof 'A'Cudzysłów "ABC"
Liczba znakówDokładnie 10 lub więcej
TypWartościowyReferencyjny
Rozmiar16 bitów (2 bajty)Zmienny

Unicode – każdy znak ma swój numer

cs/Unicode.cs C#
char literaA = 'A';
char polskieA = 'ą';
char chinski = '中';

// (int)char – konwersja na kod Unicode
Console.WriteLine($"A = {literaA} (kod: {(int)literaA})");   // kod: 65
Console.WriteLine($"ą = {polskieA} (kod: {(int)polskieA})"); // kod: 261
Console.WriteLine($"中 = {chinski} (kod: {(int)chinski})");  // kod: 20013
Co to jest Unicode?

Unicode to standard, który przypisuje każdemu znakowi na świecie unikalny numer. Dzięki temu C# obsługuje polskie znaki (ą, ę, ć), emoji, znaki chińskie i wiele innych. ASCII (0-127) to podzbiór Unicode dla podstawowych znaków angielskich.

02

Tworzenie zmiennych char

Zmienną char można utworzyć na kilka sposobów.

cs/TworzenieChar.cs C#
// 1. Bezpośrednie przypisanie znaku
char litera = 'X';
char cyfra = '7';
char znak = '@';

// 2. Przez kod Unicode (konwersja z int)
char literaA = (char)65;       // 'A' (kod ASCII 65)
char literaB = (char)66;       // 'B'

// 3. Przez zapis Unicode hex
char literaC = '\u0043';      // 'C' (hex 43 = 67 dziesiętnie)
char polskieL = '\u0142';     // 'ł'

Znaki specjalne (escape sequences)

Niektóre znaki nie da się wpisać bezpośrednio – używamy sekwencji ucieczki:

cs/ZnakiSpecjalne.cs C#
char tab = '\t';           // Tabulator
char nowaLinia = '\n';      // Nowa linia
char backslash = '\\';      // Ukośnik wsteczny \
char apostrof = '\'';       // Apostrof '
char cudzyslow = '\"';      // Cudzysłów "

Console.WriteLine($"Tab:|{tab}|koniec");
Console.WriteLine($"Backslash: {backslash}");
Console.WriteLine($"Apostrof: {apostrof}");
SekwencjaZnaczenieOpis
\tTabulatorWcięcie (jak Tab na klawiaturze)
\nNowa liniaPrzejście do nowej linii
\\BackslashPojedynczy znak \
\'ApostrofPojedynczy znak ’
\"CudzysłówPojedynczy znak „
\rPowrót karetkiRzadko używany
Dlaczego \\ zamiast \?

Backslash \ rozpoczyna sekwencję ucieczki. Żeby wstawić sam backslash, musisz napisać \\ – pierwszy „ucieka” przed drugim.

03

Konwersje między typami

Typ char można konwertować na int (kod Unicode), string i odwrotnie.

char
’A’
int
65
string
„A”
cs/Konwersje.cs C#
// char → int (kod Unicode)
char znak = 'B';
int kod = (int)znak;
Console.WriteLine($"'{znak}' ma kod: {kod}");  // 'B' ma kod: 66

// int → char
int kodLitery = 67;
char litera = (char)kodLitery;
Console.WriteLine($"Kod {kodLitery} to: '{litera}'");  // 'C'

// char → string
char pojedynczy = 'D';
string tekst = pojedynczy.ToString();
// lub:
string tekst2 = $"{pojedynczy}";

// string → char (pierwszy znak)
string napis = "Hello";
char pierwszyZnak = napis[0];
Console.WriteLine($"Pierwszy znak: '{pierwszyZnak}'");  // 'H'
KonwersjaSkładniaOpis
char → int(int)znakPobiera kod Unicode znaku
int → char(char)liczbaTworzy znak z kodu Unicode
char → stringznak.ToString()Tworzy string z 1 znaku
string → chartekst[indeks]Pobiera znak z pozycji
04

Metody klasyfikacji znaków

Klasa char ma wiele statycznych metod do sprawdzania, jakiego typu jest dany znak.

cs/Klasyfikacja.cs C#
char[] znaki = { 'A', 'a', '5', ' ', '@', 'ą', '.' };

foreach (char c in znaki)
{
    Console.WriteLine($"\nZnak: '{c}' (kod: {(int)c})");
    Console.WriteLine($"  Litera: {char.IsLetter(c)}");
    Console.WriteLine($"  Cyfra: {char.IsDigit(c)}");
    Console.WriteLine($"  Biały znak: {char.IsWhiteSpace(c)}");
    Console.WriteLine($"  Wielka litera: {char.IsUpper(c)}");
    Console.WriteLine($"  Mała litera: {char.IsLower(c)}");
}

Najważniejsze metody char.Is…()

MetodaCo sprawdza?Przykłady true
char.IsLetter(c)Czy to litera?A, a, ą, Ć, ł
char.IsDigit(c)Czy to cyfra?0, 1, 5, 9
char.IsLetterOrDigit(c)Litera lub cyfra?A, 5, ę
char.IsWhiteSpace(c)Biały znak?spacja, \t, \n
char.IsUpper(c)Wielka litera?A, B, Ą, Ć
char.IsLower(c)Mała litera?a, b, ą, ć
char.IsPunctuation(c)Interpunkcja?. , ! ? ; :
char.IsSymbol(c)Symbol?@ # $ % & *
char.IsControl(c)Znak kontrolny?\n, \t, \r
Polskie znaki też działają!

char.IsLetter('ą') zwraca true!
char.IsLower('ą') zwraca true!
Te metody obsługują wszystkie znaki Unicode, nie tylko angielskie.

05

Konwersja wielkości liter

cs/WielkoscLiter.cs C#
char[] litery = { 'A', 'b', 'Ć', 'ł', '5', '@' };

Console.WriteLine("Oryginał → Wielka → Mała");
Console.WriteLine("-------------------------");

foreach (char c in litery)
{
    char wielka = char.ToUpper(c);
    char mala = char.ToLower(c);
    Console.WriteLine($"   '{c}'   →   '{wielka}'   →   '{mala}'");
}

// Wynik:
//    'A'   →   'A'   →   'a'
//    'b'   →   'B'   →   'b'
//    'Ć'   →   'Ć'   →   'ć'
//    'ł'   →   'Ł'   →   'ł'
//    '5'   →   '5'   →   '5'   ← cyfry bez zmian
//    '@'   →   '@'   →   '@'   ← symbole bez zmian
ToUpper() i ToLower()

char.ToUpper(c) – zamienia na wielką literę
char.ToLower(c) – zamienia na małą literę
Jeśli znak nie jest literą (np. cyfra, symbol) – zwraca oryginalny znak bez zmian.

06

Operacje arytmetyczne na znakach

Ponieważ char to tak naprawdę liczba (kod Unicode), możemy wykonywać na nim operacje arytmetyczne!

cs/ArytmetykaChar.cs C#
// Dodawanie do znaku
char a = 'A';
char b = (char)(a + 1);   // 'B'
char z = (char)(a + 25);  // 'Z'

Console.WriteLine($"'{a}' + 1 = '{b}'");   // 'A' + 1 = 'B'
Console.WriteLine($"'{a}' + 25 = '{z}'");  // 'A' + 25 = 'Z'

// Różnica między znakami
char x = 'X';
char y = 'A';
int roznica = x - y;  // 23 (X=88, A=65, różnica=23)
Console.WriteLine($"'{x}' - '{y}' = {roznica}");

// Przechodzenie przez alfabet
Console.Write("Alfabet: ");
for (char litera = 'A'; litera <= 'Z'; litera++)
{
    Console.Write($"{litera} ");
}
// Wynik: A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

Konwersja cyfry-znaku na liczbę

cs/CyfraNaLiczbe.cs C#
// Znak '7' to NIE to samo co liczba 7!
char cyfraZnak = '7';

// Sposób 1: odejmij '0' (kod '0' = 48, kod '7' = 55, różnica = 7)
int cyfraLiczba = cyfraZnak - '0';
Console.WriteLine($"Znak '{cyfraZnak}' jako liczba: {cyfraLiczba}");  // 7

// Sposób 2: char.GetNumericValue() – zwraca double
double wartosc = char.GetNumericValue(cyfraZnak);
Console.WriteLine($"GetNumericValue: {wartosc}");  // 7
Dlaczego cyfraZnak – '0′ działa?

Kody cyfr w Unicode idą po kolei: '0’=48, '1’=49, '2’=50, …, '9’=57.
Odejmując '0′ (48) od dowolnej cyfry, otrzymujemy jej wartość liczbową:
'7' - '0' = 55 - 48 = 7

07

Praktyczne zastosowania

Walidacja loginu

Sprawdzamy czy login spełnia wymagania: 3-15 znaków, tylko litery, cyfry i podkreślnik, zaczyna się od litery.

cs/WalidacjaLoginu.cs C#
static bool CzyPrawidlowyLogin(string login)
{
    // Sprawdź długość
    if (login.Length < 3 || login.Length > 15)
        return false;

    // Pierwszy znak musi być literą
    if (!char.IsLetter(login[0]))
        return false;

    // Każdy znak musi być literą, cyfrą lub _
    foreach (char c in login)
    {
        if (!char.IsLetterOrDigit(c) && c != '_')
        {
            return false;
        }
    }

    return true;
}

// Testowanie
string[] loginy = { "user1", "123abc", "a", "User_123", "user@123" };

foreach (string login in loginy)
{
    bool ok = CzyPrawidlowyLogin(login);
    Console.WriteLine($"Login '{login}': {(ok ? "✅ OK" : "❌ Błędny")}");
}

// Wynik:
// Login 'user1': ✅ OK
// Login '123abc': ❌ Błędny (zaczyna się od cyfry)
// Login 'a': ❌ Błędny (za krótki)
// Login 'User_123': ✅ OK
// Login 'user@123': ❌ Błędny (zawiera @)

Liczenie znaków w tekście

cs/LiczenieZnakow.cs C#
string tekst = "Ala ma 2 koty i 3 psy!";

int litery = 0, cyfry = 0, spacje = 0, inne = 0;

foreach (char c in tekst)
{
    if (char.IsLetter(c))
        litery++;
    else if (char.IsDigit(c))
        cyfry++;
    else if (char.IsWhiteSpace(c))
        spacje++;
    else
        inne++;
}

Console.WriteLine($"Tekst: {tekst}");
Console.WriteLine($"Litery: {litery}, Cyfry: {cyfry}, Spacje: {spacje}, Inne: {inne}");
// Litery: 13, Cyfry: 2, Spacje: 5, Inne: 1
08

Częste błędy i pułapki

❌ Błąd 1: Mylenie cudzysłowów

❌ Źle

char znak = "A";
Błąd kompilacji – to string, nie char!

✅ Dobrze

char znak = 'A';
Apostrof dla char

❌ Błąd 2: Porównywanie bez uwzględnienia wielkości

❌ Niebezpieczne

if (input == 'A')
Nie zadziała dla 'a’!

✅ Bezpieczne

if (char.ToUpper(input) == 'A')
Zadziała dla 'a’ i 'A’

❌ Błąd 3: Błędne założenia o polskich znakach

❌ Źle

if (c >= 'a' && c <= 'z')
'ą' ma kod 261 – poza zakresem a-z!

✅ Dobrze

if (char.IsLower(c))
Rozpoznaje polskie znaki!

Złota zasada

Zawsze używaj metod char.IsLetter(), char.IsDigit() itd. zamiast porównywania zakresów c >= 'a' && c <= 'z'. Metody obsługują wszystkie języki!

09

Podsumowanie

Najważniejsze metody char

KategoriaMetody
KlasyfikacjaIsLetter(), IsDigit(), IsLetterOrDigit(), IsWhiteSpace()
Wielkość literIsUpper(), IsLower(), ToUpper(), ToLower()
InneIsPunctuation(), IsSymbol(), IsControl()
Konwersja(int)char, (char)int, ToString(), GetNumericValue()

Podstawowe kody ASCII

ZakresZnakiKody
Cyfry0-948-57
Wielkie literyA-Z65-90
Małe literya-z97-122
Spacja(spacja)32
Zadania

Zadania praktyczne

📝 Zadanie 1: Klasyfikator znaków

Napisz program, który:

  • Pobiera od użytkownika ciąg znaków
  • Dla każdego znaku wyświetla: znak, kod Unicode, typ (litera/cyfra/spacja/inny)
  • Na końcu wyświetla statystyki: ile liter, cyfr, spacji i innych

📝 Zadanie 2: Walidator kodu pocztowego

Napisz funkcję CzyPoprawnyKodPocztowy(string kod), która:

  • Sprawdza format: 2 cyfry, myślnik, 3 cyfry (np. "12-345")
  • Używa char.IsDigit() do walidacji cyfr
  • Zwraca true lub false

💡 Podpowiedź: kod.Length == 6 i kod[2] == '-'

📝 Zadanie 3: Szyfr Cezara

Napisz funkcję SzyfrujCezar(string tekst, int przesuniecie), która:

  • Przesuwa każdą literę o przesuniecie pozycji w alfabecie
  • Zachowuje wielkość liter (A→B, a→b)
  • Pomija znaki nie-literowe (zostawia bez zmian)

💡 Podpowiedź: (char)('A' + (c - 'A' + przesuniecie) % 26)

⭐ Zadanie 4: Analiza hasła

Napisz funkcję OcenHaslo(string haslo), która:

  • Sprawdza czy hasło zawiera: małą literę, wielką literę, cyfrę, znak specjalny
  • Przyznaje punkty: +1 za każdą kategorię, +1 za długość ≥12
  • Zwraca ocenę: "Słabe" (0-2), "Średnie" (3), "Silne" (4), "Bardzo silne" (5)

⭐⭐ Zadanie 5: Analiza częstotliwości liter

Napisz program, który:

  • Wczytuje tekst od użytkownika
  • Liczy wystąpienia każdej litery (ignorując wielkość)
  • Wyświetla wykres słupkowy w konsoli używając znaków
  • Pokazuje top 5 najczęstszych liter

💡 Podpowiedź: Użyj tablicy int[26] dla liter A-Z