Procvič si angličtinu zdarma s naším americkým e-learningem! Learn more
Pouze tento týden sleva až 80 % na celý Java e-learning!

Lekce 9 - Textové řetězce v C# podruhé - práce s jednotlivými znaky

Unicorn College Tento obsah je dostupný zdarma v rámci projektu IT lidem.
Vydávání, hosting a aktualizace umožňují jeho sponzoři.

V milé lekci kurzu, Pole v C#, jsme se naučili pracovat s polem. Pokud jste vycítili v C# nějakou podobnost mezi polem a textovým řetězcem, tak jste vycítili správně. Pro ostatní může být překvapením, že string je v podstatě pole znaků (charů) a můžeme s ním i takto pracovat.

Nejprve si vyzkoušejme, že to všechno funguje. Rozcvičíme se na jednoduchém vypsání znaku na dané pozici:

string s = "Ahoj ITnetwork";
Console.WriteLine(s);
Console.WriteLine(s[2]);
Console.ReadKey();

Výstup:

Ahoj ITnetwork
o

Vidíme, že můžeme ke znakům v řetězci přistupovat přes hranatou závorku, jako tomu je i u pole. Zklamáním může být, že znaky na dané pozici jsou v C# read-only, nemůžeme tedy napsat:

string s = "Ahoj ITnetwork";
s[1] = "o";
Console.WriteLine(s);
Console.ReadKey();

Samozřejmě to jde udělat jinak, později si to ukážeme, zatím se budeme věnovat pouze čtení jednotlivých znaků.

Analýza výskytu znaků ve větě

Napišme si jednoduchý program, který nám analyzuje zadanou větu. Bude nás zajímat počet samohlásek, souhlásek a počet nepísmenných znaků (např. mezera nebo !).

Daný textový řetězec si nejprve v programu zadáme napevno, abychom ho nemuseli při každém spuštění psát. Až bude program hotový, nahradíme ho Console.ReadLine(). Řetězec budeme projíždět cyklem po jednom znaku. Rovnou zde říkám, že neapelujeme na rychlost programu a budeme volit názorná a jednoduchá řešení.

Nejprve si připravme kód, definujme si samohlásky a souhlásky. Počet ostatních znaků nemusíme počítat, bude to délka řetězce mínus samohlásky a souhlásky. Abychom nemuseli řešit velikost písmen, celý řetězec na začátku převedeme na malá písmena. Připravme si proměnné, do kterých budeme ukládat jednotlivé počty. Protože se jedná o složitější kód, nebudeme zapomínat na komentáře.

// řetězec, který chceme analyzovat
string s = "Programátor se zasekne ve sprše, protože instrukce na šampónu byly: Namydlit, omýt, opakovat.";
Console.WriteLine(s);
s = s.ToLower();

// inicializace počítadel
int pocetSamohlasek = 0;
int pocetSouhlasek = 0;

// definice typů znaků
string samohlasky = "aeiouyáéěíóúůý";
string souhlasky = "bcčdďfghjklmnpqrřsštťvwxzž";

// hlavní cyklus
foreach (char c in s)
{

}

Console.ReadKey();

Zpočátku si připravíme řetězec a převedeme ho na malá písmena. Počítadla vynulujeme. Na definice znaků nám postačí obyčejné stringy. Hlavní cyklus nám projede jednotlivé znaky v řetězci s, přičemž v každé iteraci cyklu bude v proměnné c aktuální znak.

Pojďme plnit počítadla, pro jednoduchost již nebudu opisovat zbytek kódu a přesunu se jen k cyklu:

// hlavní cyklus
foreach (char c in s)
{
    if (samohlasky.Contains(c))
        pocetSamohlasek++;
    else
    if (souhlasky.Contains(c))
        pocetSouhlasek++;
}

Metodu Contains() na řetězci již známe, jako parametr ji lze předat jak podřetězec, tak přímo znak. Daný znak c naší věty tedy nejprve zkusíme vyhledat v řetězci samohlasky a případně zvýšit jejich počítadlo. Pokud v samohláskách není, podíváme se do souhlásek a případně opětovně zvýšíme jejich počítadlo.

Nyní nám chybí již jen výpis na konec:

Console.WriteLine("Samohlásek: {0}", pocetSamohlasek);
Console.WriteLine("Souhlásek: {0}", pocetSouhlasek);
Console.WriteLine("Nepísmenných znaků: {0}", s.Length - (pocetSamohlasek + pocetSouhlasek));

Konzolová aplikace
Programátor se zasekne ve sprše, protože instrukce na šampónu byly: Namydlit, omýt, opakovat.
Samohlásek: 31
Souhlásek: 45
Nepísmenných znaků: 17

A je to!

ASCII hodnota

Možná jste již někdy slyšeli o ASCII tabulce. Zejména v éře operačního systému MS-DOS prakticky nebyla jiná možnost, jak zaznamenávat text. Jednotlivé znaky byly uloženy jako čísla typu byte, tedy s rozsahem hodnot od 0 do 255. V systému byla uložena tzv. ASCII tabulka, která měla 256 znaků a každému ASCII kódu (číselnému kódu) přiřazovala jeden znak.

Asi je vám jasné, proč tento způsob nepřetrval dodnes. Do tabulky se jednoduše nevešly všechny znaky všech národních abeced. Nyní se používá Unicode (UTF-8) kódování, kde jsou znaky reprezentovány trochu jiným způsobem. V C# máme možnost pracovat s ASCII hodnotami jednotlivých znaků. Hlavní výhoda je v tom, že znaky jsou uloženy v tabulce za sebou, podle abecedy. Např. na pozici 97 nalezneme 'a', na 98 'b' a podobně. Podobně je to s čísly, diakritické znaky tam budou bohužel jen nějak rozházeny.

Zkusme si nyní převést znak do jeho ASCII hodnoty a naopak podle ASCII hodnoty daný znak vytvořit:

char c; // znak
int i; // ordinální (ASCII) hodnota znaku
// převedeme znak na jeho ASCII hodnotu
c = 'a';
i = (int)c;
Console.WriteLine("Znak {0} jsme převedli na ASCII hodnotu {1}", c, i);
// Převedeme ASCII hodnotu na znak
i = 98;
c = (char)i;
Console.WriteLine("ASCII hodnotu {1} jsme převedli na znak {0}", c, i);
Console.ReadKey();

Převodům se říká přetypování, ale o tom se blíže pobavíme až později.

Cézarova šifra

Vytvoříme si jednoduchý program pro šifrování textu. Pokud jste někdy slyšeli o Cézarově šifře, bude to přesně to, co si zde naprogramujeme. Šifrování textu spočívá v posouvání znaku v abecedě o určitý, pevně stanovený počet znaků. Například slovo "ahoj" se s posunem textu o 1 přeloží jako "bipk". Posun umožníme uživateli vybrat. Algoritmus zde máme samozřejmě opět vysvětlený a to v článku Cézarova šifra. Program si dokonce můžete vyzkoušet v praxi - Online cézarova šifra.

Vraťme se k programování a připravme si kód. Budeme potřebovat proměnné pro původní text, zašifrovanou zprávu a pro posun. Dále cyklus projíždějící jednotlivé znaky a výpis zašifrované zprávy. Zprávu si necháme zapsanou napevno v kódu, abychom ji nemuseli při každém spuštění programu psát. Po dokončení nahradíme obsah proměnné metodou Console.ReadLine(). Šifra nepočítá s diakritikou, mezerami a interpunkčními znaménky. Diakritiku budeme bojkovat a budeme předpokládat, že ji uživatel nebude zadávat. Ideálně bychom poté měli diakritiku před šifrováním odstranit, stejně tak cokoli kromě písmen.

// inicializace proměnných
string s = "cernediryjsoutamkdebuhdelilnulou";
Console.WriteLine("Původní zpráva: {0}", s);
string zprava = "";
int posun = 1;

// cyklus projíždějící jednotlivé znaky
foreach(char c in s)
{

}

// výpis
Console.WriteLine("Zašifrovaná zpráva: {0}", zprava);
Console.ReadKey();

Nyní se přesuneme dovnitř cyklu, převedeme znak v c na ASCII hodnotu (neboli ordinální hodnotu), tuto hodnotu zvýšíme o posun a převedeme zpět na znak. Tento znak nakonec připojíme k výsledné zprávě:

int i = (int)c;
i += posun;
char znak = (char)i;
zprava += znak;

Konzolová aplikace
Původní zpráva: cernediryjsoutamkdebuhdelilnulou
Zašifrovaná zpráva: dfsofejszktpvubnlefcviefmjmovmpv

Program si vyzkoušíme. Výsledek vypadá docela dobře. Zkusme si však zadat vyšší posun nebo napsat slovo "zebra". Vidíme, že znaky mohou po 'z' přetéct do ASCII hodnot dalších znaků, v textu tedy již nemáme jen písmena, ale další ošklivé znaky. Uzavřeme znaky do kruhu tak, aby posun plynule po 'z' přešel opět k 'a' a dále. Postačí nám k tomu jednoduchá podmínka, která od nové ASCII hodnoty odečte celou abecedu tak, abychom začínali opět na 'a'.

int i = (int)c;
i += posun;
// kontrola přetečení
if (i > (int)'z')
    i -= 26;
char znak = (char)i;
zprava += znak;

Pokud i přesáhne ASCII hodnotu 'z', snížíme ho o 26 znaků (tolik znaků má anglická abeceda). Operátor -= vykoná to samé, jako bychom napsali i = i - 26. Je to jednoduché a náš program je nyní funkční. Všimněme si, že nikde nepoužíváme přímé kódy znaků, v podmínce je (int)'z', i když bychom tam mohli napsat rovnou 122. Je to z důvodu, aby byl náš program plně odstíněn od explicitních ASCII hodnot a bylo lépe viditelné, jak funguje. Cvičně si zkuste udělat dešifrování.

V příští lekci, Textové řetězce v C# do třetice - Split a Join, si ukážeme, že string umí přeci jen ještě něco navíc. Prozradím, že budeme dekódovat Morzeovu abecedu.


 

Stáhnout

Staženo 1111x (48.75 kB)
Aplikace je včetně zdrojových kódů v jazyce C#

 

 

Článek pro vás napsal David Čápka
Avatar
Jak se ti líbí článek?
43 hlasů
Autor pracuje jako softwarový architekt a pedagog na projektu ITnetwork.cz (a jeho zahraničních verzích). Velmi si váží svobody podnikání v naší zemi a věří, že když se člověk neštítí práce, tak dokáže úplně cokoli.
Unicorn College Autor sítě se informační technologie naučil na Unicorn College - prestižní soukromé vysoké škole IT a ekonomie.
Předchozí článek
Pole v C#
Všechny články v sekci
Základní konstrukce jazyka C#
Miniatura
Následující článek
Cvičení k 9. lekci C# .NET
Aktivity (12)

 

 

Komentáře

Avatar
Theodor Johnson
Redaktor
Avatar
Theodor Johnson:9.8.2012 20:37

Moc se mi tenhle styl učení líbí, ale chybí mi tady jediná věc: samostatná práce, ale jinak je to fakt perfektní

Odpovědět 9.8.2012 20:37
Mo8ilε 15 Ѐλđ
Avatar
Mediel
Redaktor
Avatar
Mediel:18.9.2012 0:07

Chtel jsme se zeptat, kdybych chtel sifrovat text podle nejakeho slova? Lze to u teto sifry?

Odpovědět 18.9.2012 0:07
Nechci vám ukazovat, jak dobrý jsem já ... Chci vám ukázat, jak dobrý můžete být vy ... Když uvěříte ... V sami sebe...
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Mediel
David Čápka:18.9.2012 9:44

Určitě to jde, viz algoritmus na Vernamovu šifru: http://www.itnetwork.cz/…namovi-sifry

Je tam kód v PHP, ale to jistě zvládneš odvodit.

Odpovědět 18.9.2012 9:44
Jsem moc rád, že jsi na síti, a přeji ti top IT kariéru, ať jako zaměstnanec nebo podnikatel. Máš na to! :)
Avatar
Kit
Redaktor
Avatar
Odpovídá na Mediel
Kit:18.9.2012 11:10

Tohle šifrování ber jenom jako ukázku algoritmizace. Pokud budeš chtít opravdu šifrovat, použij některý z šifrovacích programů.

Odpovědět 18.9.2012 11:10
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Kit
David Čápka:18.9.2012 11:47

Jo, to je také dobré podotknout :)

C# má jmenný prostor System.Securi­ty.Cryptograp­hy, dá se tam najít dost zajímavých věcí.

Odpovědět  +1 18.9.2012 11:47
Jsem moc rád, že jsi na síti, a přeji ti top IT kariéru, ať jako zaměstnanec nebo podnikatel. Máš na to! :)
Avatar
Kit
Redaktor
Avatar
Kit:20.10.2012 14:52
foreach(char c in "žluťoučký") {
   Console.Write("{0} ", (int)c );
}

Výstup:

382 108 117 357 111 117 269 107 253

Výsledek už není ani ASCII, ani UTF-8, ale Unicode.

Odpovědět 20.10.2012 14:52
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
sucak
Člen
Avatar
sucak:18.12.2012 13:06

Nepsaným znakum se říká bíle znaky :)

 
Odpovědět 18.12.2012 13:06
Avatar
mienkofax
Člen
Avatar
mienkofax:3.2.2013 9:39

Doma som skúšal ten príklad s analýzou výskytu znaku v stringu. Len mne vkuse vypíše v cykle, že nemožno konvertovať from char na string a to isté mi vypísalo aj pri ukážkovom príklade, ktorý sa dá stiahnuť. Kde je problém ?

 
Odpovědět  +1 3.2.2013 9:39
Avatar
matesax
Redaktor
Avatar
Odpovídá na mienkofax
matesax:3.2.2013 9:43

Proč lidi zásadně nevloží problematický kód? Jsem snad jasnovidec? :) Ale i tak - nechápu, proč píšeš sem - když problém víš... Tak nepoužívej string, ale char... (String je pole char.)

foreach (char letter in letters)
    ddd

Prostě to co získáš procházením stringu jsou charactery...

 
Odpovědět 3.2.2013 9:43
Avatar
Mike
Neregistrovaný
Avatar
Odpovídá na sucak
Mike:5.2.2013 15:29

S tím se bohužel nedá souhlasit :) Resp. otázka zněla jak se říka "nePÍsmenným znakům", kam napřiklad patří taky čáky, uvozovky, etc. ;-)

Napadá mně symbol, ale tam by zase spadaly i "normální" písmena :) Takže možná speciální znaky?

 
Odpovědět 5.2.2013 15:29
Avatar
samo007
Redaktor
Avatar
samo007:12.2.2013 16:54

A prečo nemôžme nechať tie divné znaky, keď to ide rozšifrovať? Aspoň to bude presné a ten, kto sa k šifre dostane, nebude ju môcť rozlúštiť :D
Čo tak to zauzliť? (skúste si moju šifru)

// premenné
string s = "Povodňová aktivita a selzmické vlny.";
Console.WriteLine("Pôvodná správa: {0}", s);
string sprava = "";
int posun = 1;
int posun2 = 2;

// cyklus prechádzajúci jednotlivé znaky
foreach (char c in s)
{
    int i = (int)c;
    i += posun;
    i *= posun2;
    i -= (2 + posun);
    char znak = (char)i;
    sprava += znak;
}
Console.WriteLine("Zašifrovaná správa: {0}", sprava);

// premenné pre rozšifrovanie
string z = sprava;
sprava = "";

// cyklus pre rozšifrovanie
foreach (char c in z)
{
    int i = (int)c;
    i += (2 + posun);
    i /= posun2;
    i -= posun;
    char znak = (char)i;
    sprava += znak;
}
Console.WriteLine("Rozšifrovaná správa: {0}", sprava);
Console.ReadKey();
Editováno 12.2.2013 16:55
 
Odpovědět 12.2.2013 16:54
Avatar
burdacz
Neregistrovaný
Avatar
burdacz:25.2.2013 14:10

Ještě bych na místo

string s = "Programátor se zasekne ve sprše, protože instrukce na šampónu byly: Namydlit, omýt, opakovat.";
Console.WriteLine(s);

použil

Console.WriteLine("Napiste slovo, vetu nebo souveti.");
      string s = Console.ReadLine();
:)
 
Odpovědět 25.2.2013 14:10
Avatar
Luboš Běhounek Satik
Autoredaktor
Avatar
Odpovídá na burdacz
Luboš Běhounek Satik:25.2.2013 14:14

Já bych použil

const string s = "Programátor se zasekne ve sprše, protože instrukce na šampónu byly: Namydlit, omýt, opakovat.";
Console.WriteLine(s);
:)
Odpovědět  +1 25.2.2013 14:14
https://www.facebook.com/peasantsandcastles/
Avatar
Jan.Nygdo
Člen
Avatar
Odpovídá na mienkofax
Jan.Nygdo:12.3.2013 10:54

Ma to byt:

// hlavní cyklus
foreach (Char c in s)
{
  if (samohlasky.Contains(c.ToString()))
    pocetSamohlasek++;
  else
    if (souhlasky.Contains(c.ToString()))
      pocetSouhlasek++;
}
 
Odpovědět 12.3.2013 10:54
Avatar
Petr
Neregistrovaný
Avatar
Petr:13.3.2013 16:13

Prosim Vás, neví někdo jak by se dal tento program přepsat, abych mohl načíst text z textovyho souboru a v tomto texte by program prehazel vety ? Popripade slova ?

 
Odpovědět 13.3.2013 16:13
Avatar
Petr Nymsa
Redaktor
Avatar
Odpovídá na Petr
Petr Nymsa:13.3.2013 17:26

Podíve jse zde na zdější tutoriálay o práci se soubory :)http://www.it­network.cz/cshar­p/soubory

Odpovědět 13.3.2013 17:26
Pokrok nezastavíš, neusni a jdi s ním vpřed
Avatar
NutelaCZ
Člen
Avatar
NutelaCZ:14.9.2013 22:33

Dobrý den,
mám problém v posledním kroku Cézarovy šifry, a netuším jak ho vyřešit. Jde o to ,že i když jsem do kódu vložil

// kontrola přetečení
if (i > (int)'z')
        i -= 26;
char znak = (char)i;
zprava += znak;

vždy my výsledek výjde s ASCII hodnotou. Prosím mohl by mi někdo vysvětlit co je špatně? moc děkuji.

Celý kód:

string s = "Zebra";
            Console.WriteLine("Původní zpráva {0}", s);
            string zprava = "";
            int posun = 1;

            foreach (char c in s)
            {
                int i = (int)c;
                i = i + posun;
                if (i > (int)'z')
                {
                    i = i - 26;
                }
                char znak = (char)i;
                zprava = zprava + znak;
            }
            Console.WriteLine("Zašifrovana zprava {0}", zprava);
            Console.ReadKey();
 
Odpovědět 14.9.2013 22:33
Avatar
Kit
Redaktor
Avatar
Odpovídá na NutelaCZ
Kit:14.9.2013 23:15

Zajímavé. Když jsem to od tebe zkopíroval, tak mi to funguje jak má. Musíš tam mít ještě nějakou odlišnost, protože to co jsi poslal, je v pořádku.

http://www.itnetwork.cz/dev-lighter/201

Editováno 14.9.2013 23:17
Odpovědět 14.9.2013 23:15
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
NutelaCZ
Člen
Avatar
NutelaCZ:15.9.2013 13:07

Ahá tak jsem na to přišel kde je chyba, jelikož jsem zadal Zebra s velým Z tak to bralo jeho ASCII hodnotu jako 90 a psalo to následný znak [, teť jsem to přepsal s malým z a užto funguje jak má :)

Děkuji za pomoc :)

 
Odpovědět 15.9.2013 13:07
Avatar
Kit
Redaktor
Avatar
Odpovídá na NutelaCZ
Kit:15.9.2013 13:28

Zkus se podívat i na redukovanou verzi, která dělá totéž.
http://www.itnetwork.cz/dev-lighter/201

Odpovědět  +1 15.9.2013 13:28
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
flower-go
Člen
Avatar
flower-go:16.9.2013 21:30

Ať dělám, co dělám (a to včetně toho, že jsem si stáhla řešení), vypisuje to spoustu chyb ( nelze najít 's', nelze použít ++,etc...); Kde je chyba ?
(úpravu podle Jan.Nygdo jsem také zkoušela... :( čím to ?

 
Odpovědět 16.9.2013 21:30
Avatar
Jan Vargovský
Redaktor
Avatar
Odpovídá na flower-go
Jan Vargovský:16.9.2013 21:40

Nám pošli kód a my se nato podíváme :)

 
Odpovědět 16.9.2013 21:40
Avatar
Petr Čech
Redaktor
Avatar
Petr Čech:5.10.2013 19:08

Nepísmenný znak = entita (?) o_O

Odpovědět 5.10.2013 19:08
the cake is a lie
Avatar
Neaktivní uživatel:9.11.2013 11:32

V Cézarově šifře je chyba - "cernediryjsou­tamkdebuhdelil­nulou"
by mělo být - "cernediryjsou­tamkdepudedelit­nulou"
Jen minimální připomínka, doufám že nejsem tady jediný perfekcionista :D

Odpovědět  -1 9.11.2013 11:32
Neaktivní uživatelský účet
Avatar
Petr.M
Člen
Avatar
Petr.M:21.11.2013 8:40

Prosím o radu, jaký je rozdíl mezi

int a = 84;
char z = Convert.ToChar(a);

a

int a = 84;
char z = (char)a;

Při výstupu se to tváří stejně.

Editováno 21.11.2013 8:41
Odpovědět 21.11.2013 8:40
Sometimes you just do things. - Scott Jurek
Avatar
Jan Vargovský
Redaktor
Avatar
Odpovídá na Petr.M
Jan Vargovský:21.11.2013 8:50

Je to vpodstatě to samé. Jednou to přetypuješ a jednou zkonvertuješ.

 
Odpovědět 21.11.2013 8:50
Avatar
coells
Redaktor
Avatar
Odpovídá na Petr.M
coells:21.11.2013 9:55

Pokud máš následující kód:

int i = -1;
char c = (char)i;
char d = Convert.ToChar(i);

Pak v prvním případě dojde ke konverzi a přetypování, kdy se děje následující:

  1. int má velikost 4 byty
  2. char má velikost 2 byty
  3. vezme se hodnota int a horní 2 byty se useknou (konverze)
  4. dolní dva byty se uloží do charu (přetypování)

Ve druhém případě se vyvolá bezpečná konverze, která kontroluje obsah intu a přetečení. Poté se přejde na první případ:

public static class Convert
{
    public static char ToChar(int value)
    {
      if (value < 0 || value > (int) ushort.MaxValue)
        throw new OverflowException();
      else
        return (char) value;
    }
}

Takže obsah 'c' bude 65535 a na dalším řádku dojde k výjimce.

Editováno 21.11.2013 9:56
 
Odpovědět 21.11.2013 9:55
Avatar
Johny Lewis
Neregistrovaný
Avatar
Johny Lewis:4.1.2014 17:58

Je nějaký rozdíl mezi touto verzí

int i = (int)c;
i += posun;
char znak = (char)i;
zprava += znak;

a touto verzí (char znak jsem nahradil již definovaným c)

int i = (int)c;
i += posun;
c = (char)i;
zprava += c;
 
Odpovědět 4.1.2014 17:58
Avatar
Johny Lewis
Neregistrovaný
Avatar
Odpovídá na Johny Lewis
Johny Lewis:4.1.2014 18:01

Tak se omlouvám, myslel jsem si, že je to to samé, ale až nyní jsem to vyzkoušel a zjistil jsem, že se pak program ani nespustí :)

 
Odpovědět 4.1.2014 18:01
Avatar
Dominik Čoupek:14.1.2014 16:46

Opět velice zajímavý článek. Díky :-)

 
Odpovědět 14.1.2014 16:46
Avatar
fejjaaas
Člen
Avatar
Odpovídá na Johny Lewis
fejjaaas:19.2.2014 17:27

Johny Lewis: Pokud si vytvoříš proměnnou v cyklu foreach, zde to tvoje c, tak do ní nemůžeš v cyklu nic ukládat ani ji měnit, to nelze. Tak proto ti to nešlo spustit. ;-)

Editováno 19.2.2014 17:28
 
Odpovědět  +1 19.2.2014 17:27
Avatar
Cencek
Člen
Avatar
Cencek:20.2.2014 10:08

Nějak mi nedochází jak funguje následující část kódu, prosím o pomoc

// převedeme znak na jeho ASCII hodnotu
c = 'a';
i = (int)c;
Console.WriteLine("Znak {0} jsme převedli na ASCII hodnotu {1}", c, i);
 
Odpovědět 20.2.2014 10:08
Avatar
game4gamer
Člen
Avatar
game4gamer:12.7.2014 20:32

Nepisemny znak bude nejspis cislice ne? Pokud to myslis takto ale existuji i obrazkove znaky napr hieroglify, ale ty nejspis standardne nebudou v zadnem programovacim jazyce :-]

 
Odpovědět 12.7.2014 20:32
Avatar
Odpovídá na Cencek
Anton Arnautov:24.8.2014 15:36

Do proměnné i si uložíš ASCII hodnotu charakteru 'a' v tomto případě je to 97.

Odpovědět 24.8.2014 15:36
Don't be a salad, be the best god damn brocolli you could ever be!
Avatar
Lukáš Nový - Lunnkas:5.4.2015 22:02

Ahoj, chci se zeptat ohledně dešifrování zprávy. Podařilo se mi to udělat u běžných znaků, takže posunem o -1. Nevím ale jak vyřešit pokud bylo zadáno před šifrováním písmeno z nebo něco s vyšším ascii kódem. Podle mě můžu použít podmínku z kódu pro zašifrování takže

if (i > (int)'z')

a poté hodnotu proměnné zvýšit o 26. Jak to udělat bez použití proměnné z šfrovacího kódu opravdu nevím. (nevím jestli to je vůbec potřeba)

 
Odpovědět 5.4.2015 22:02
Avatar
jackx
Člen
Avatar
Odpovídá na Lukáš Nový - Lunnkas
jackx:9.4.2015 16:47

Co takhle si zkusit nadefinovat nějakou proměnnou, která pokaždé při splnění podmínky cyklu

if (i > (int)'z')

, se zvýší o jednu? Při dešifrování pak budeš tak dlouho točit znaky, dokud tato proměnná nebude 0. (ještě poradím dešifrovat text od zadu a na každý znak dovolit snížit kontrolní proměnnou jen o jednu ;-) )

Odpovědět 9.4.2015 16:47
Nic není nemožné.
Avatar
Lukáš Hypša:30.7.2015 12:58

Souvisí nějak ASCII s alt kódama? Pokud ano proč je alt kódů jen 255 (tedy o jeden míň)?
Předem díky za odpověď :)
(Stránka s alt kódy: http://www.alt-codes.net)

Odpovědět 30.7.2015 12:58
Jsem lama co se roky snaží naučit napsat aspoň pár řádků a furt mu to nejde...
Avatar
tomisoka
Redaktor
Avatar
Odpovídá na Lukáš Hypša
tomisoka:30.7.2015 13:18

Většina dnešního kódování znaků vychází z ASCII, přesněji z těch pevně stanovených znaků 0-127.
Co koukám na ty alt kódy, tak přidávají znaky 128-255 a přepisují 1-31, 127 -> funkční znaky. Znak 0 slouží k označení konce znakového řetězce, takže ten nechávají, ale je zbytečné, aby ho v té tabulce vypisovali.

 
Odpovědět 30.7.2015 13:18
Avatar
dleducmanh6
Člen
Avatar
dleducmanh6:16.8.2015 18:13

Zdravím, nevíte kde mám v tomto programu chybu? Máte napsat heslo a jestli bude špatně, ukáže se heslo je špatně: Console.Write­Line("Heslo:");
string s = "sims";
bool sims = true;
if (s.Contains(s))
Console.WriteLine ("Vítej.");
else
Console.WriteLine ("Ne e.");
Console.ReadLine ();

 
Odpovědět 16.8.2015 18:13
Avatar
Insane Qurd
Redaktor
Avatar
Odpovídá na dleducmanh6
Insane Qurd:16.8.2015 18:23

Ahoj, asi myslíš tohle:

Console.Write("Heslo");
if (Console.ReadLine() == "sims")
   Console.WriteLine("vítej");
else
   Console.WriteLine("ne");

contains nepoužívej, to ti to pak vezme každý textový řetězec obsahující s

Odpovědět 16.8.2015 18:23
It's impossible to say it's impossible.
Avatar
dleducmanh6
Člen
Avatar
dleducmanh6:17.8.2015 10:41

Ne, myslel jsem to s 1 porměnnou navíc asi takhle: Console.Write­Line("Zadej heslo:");
string h = "sims";
string s = string.parse (Console.Read­Line());
if (h != s)
Console.WriteLine ("Vítej");
else
Console.WriteLine ("Zadané heslo je špatně");
Console.ReadLine ();
Ale pořád nevím co je tam špatně :/.

 
Odpovědět 17.8.2015 10:41
Avatar
dleducmanh6
Člen
Avatar
dleducmanh6:17.8.2015 13:21

nevíte někdo jak to udělat? :/

 
Odpovědět 17.8.2015 13:21
Avatar
Milan Křepelka
Redaktor
Avatar
Odpovídá na dleducmanh6
Milan Křepelka:17.8.2015 13:41
Console.WriteLine("Zadej heslo:");
string h = "sims";
string s = Console.ReadLine();
if (h.Equals(s))
    Console.WriteLine("Vítej");
else
    Console.WriteLine("Zadané heslo je špatně");
Console.ReadLine();
 
Odpovědět  +1 17.8.2015 13:41
Avatar
krepsy3
Redaktor
Avatar
Odpovídá na Lukáš Nový - Lunnkas
krepsy3:5.10.2015 17:39

Když jsi při šifrování prováděl:
if (c == 'z')
c = (char((int)c - 26)

Tak musíš při dešifrování udělat pravý opak:
if (c == 'a')
c = (char)((int)c + 26)

Protože tam, kde se při šifrování ošetřovalo "maximum" písmeno z,
tam se nyní ošetřuje "minimum" písmeno a ;)

Odpovědět  +1 5.10.2015 17:39
Programátor je stroj k převodu kávy na kód.
Avatar
krepsy3
Redaktor
Avatar
Odpovídá na krepsy3
krepsy3:5.10.2015 17:45

Kecám, promiň: ;)
šifrace:
if (c > (int)'z')
c = (char((int)c - 26)

dešifrace:
if (c < (int)'a')
c = (char((int)c + 26)

Odpovědět 5.10.2015 17:45
Programátor je stroj k převodu kávy na kód.
Avatar
rimodar65
Člen
Avatar
rimodar65:30.1.2016 22:50

Nějakmi nejde drobná úprava
>
Analýza výskytu znaků ve větě
>

Console.WriteLine("Zadej slova a já ti spočítám samohlásky, souhlásky a mezery.Zadávání ukonči ENTEREM");
           String s = Console.ReadLine();
            int a = int.Parse(s);
            Console.WriteLine(s);//TOHLE MI NEJDE
            while (a > 0)
            {

           s = s.ToLower();// převod na malá písmena
           // inicializace počítadel
           int pocetSamohlasek = 0;
           int pocetSouhlasek = 0;

           // definice typů znaků
           string samohlasky = "aeiouyáéěíóúůý";
           string souhlasky = "bcčdďfghjklmnpqrřsštťvwxzž";

           // hlavní cyklus
           foreach (char c in s)
           {
               if (samohlasky.Contains(c))//contains prohledá c jestli se v ní nachází samohlásky
                   pocetSamohlasek++;
               else
                   if (souhlasky.Contains(c))
                       pocetSouhlasek++;
           }
           Console.WriteLine("Samohlásek: {0}", pocetSamohlasek);
           Console.WriteLine("Souhlásek: {0}", pocetSouhlasek);
           Console.WriteLine("Nepísmenných znaků: {0}", s.Length - (pocetSamohlasek + pocetSouhlasek));
           Console.WriteLine("Znaků je celkem:{0}", pocetSamohlasek + pocetSouhlasek);

           Console.ReadKey();
 
Odpovědět 30.1.2016 22:50
Avatar
rimodar65
Člen
Avatar
rimodar65:30.1.2016 23:04

Po přečtení dřívějších dílů asi chápu chybu,tak na to jdu jinak.....

 
Odpovědět 30.1.2016 23:04
Avatar
Dominik Gavrecký:10.4.2016 23:01

Nech sa na to pozriem ako chcem nerozumiem prečo práve "char c". Rozumiem že sme určili dátoví typ na char premene c ale čo ta premenná obsahuje ? Je to nejaká špeciálna metoda ktorá rozoberie string na jednotlivé hodnoti pola a už ho len prechádza práve cez to in ? Mohol by mi to niekto logický popísať ? Ďakujem

// hlavní cyklus
foreach (char c in s)
{

}
Odpovědět  +2 10.4.2016 23:01
Hlupák nie je ten kto niečo nevie, hlupákom sa stávaš v momente keď sa na to bojíš opýtať.
Avatar
Petr Stastny
Redaktor
Avatar
Petr Stastny:18.4.2016 10:50

Ahoj, to počitadlo souhlásek, samohlásek atd by šlo udělat jednodušeji:

string s = "Programátor se zasekne ve sprše, protože instrukce na šampónu byly: Namydlit, omýt, opakovat.";

            s = s.ToLower();

            int a = 0;
            int b = 0;
            int c = 0;

            string samo = "aeiouyáéěíóúůý";
            string sou = "bcčdďfghjklmnpqrřsštťvwxzž";


            foreach (char h in s)
            {
                if (samo.Contains(h))
                    a++;
                else if (sou.Contains(h))
                    b++;
                else
                    c++;

            }
            Console.WriteLine("Samohlasek: {0} | Souhlasek: {1} | Ostatni znaky: {2}", a, b, c);
            Console.ReadKey();
 
Odpovědět  +5 18.4.2016 10:50
Avatar
Odpovídá na Dominik Gavrecký
Dávid Šutor:14.5.2016 20:49
// hlavní cyklus
foreach (char c in s)
{

}

Tento cyklus funguje následovne. Keď cyklus začne, premenná c nadobudne hodnotu prvého znaku (char) v stringu s. Po vykonaní príkazov v tele cyklu premenná c nadobudne hodnotu ďalšieho znaku (char). Takto to bude pokračovať do vtedy, kým neprejde všetky znaky (char). Premenná c bude iba nadobúdať char.

 
Odpovědět  +1 14.5.2016 20:49
Avatar
Petr Stastny
Redaktor
Avatar
Petr Stastny:14.5.2016 21:20

A ohledně ASCII, tohle je trochu delší, ale dobře to ukazuje, jak jde s ASCII pracovat :)

http://www.itnetwork.cz/dev-lighter/732

 
Odpovědět 14.5.2016 21:20
Avatar
Robert
Člen
Avatar
Robert:20.10.2016 22:26

//3. Cézarova šifra:
Console.Write­Line("Zadaj ľubovoľný reťazec a ja ho zašifrujem.");
Console.Write­Line("POZOR!!! Zapisuj bez diakritiky a bez medzier!");
Console.Write("Tex­t: ");

string sprava = Console.ReadLine();

//Opýtať sa na hodnotu posunu
Console.Write("O akú hodnotu chceš posúvať text? [napr. o 2 znaky...]:");
int posun = int.Parse(Con­sole.ReadLine());
Console.Write­Line();
Console.Write­Line("Povodná správa: {0}", sprava);
sprava = sprava.ToLower();

//dekloarovanie premennej pre uloženie zašifrovanej správy
string sifrovana = "";

foreach(char z in sprava){

int j = (int)z;
j += posun;

//kontrola pretečenia!!!
if(j > (int)'z'){
j -= 26;
}

char znak = (char)j;
sifrovana += znak;
}
Console.Write­Line("Zašifro­vaná správa: {0}", sifrovana);

string desifrovana = "";

//Dešifrovanie správy
Console.Write­Line("Dešifro­vanie zašifrovanej správy: {0}", sifrovana);
foreach(char z in sifrovana){
int j = (int)z;
j -= posun;

//Kontrola pretečenia
if(j<(int)'a'){
j += 26;
}

char znak = (char)j;
desifrovana += znak;

}

Console.Write­Line("Dešifro­vaná správa: {0}", desifrovana);

 
Odpovědět 20.10.2016 22:26
Avatar
Ariska
Člen
Avatar
Ariska:27.4.2017 16:03

Nepísemné znaky jsou speciální znaky. I v samotném MSWordu máte volbu vložení speciálních znaků, kde jsou právě mezery, uvozovky apod. Symbol by se taktéž dal použít, ale ten se často špatně interpretuje. Navíc speciální znaky jsou konkrétněji a úzce zaměřovány, kdežto symboly pojímají větší škálu znaků (jako např. ü, ŕ). :)

 
Odpovědět 27.4.2017 16:03
Avatar
Odpovídá na rimodar65
Radek Novotný:17.6.2017 10:37

máš tam u string velké S

 
Odpovědět 17.6.2017 10:37
Avatar
Ondřej Čech:7.10.2017 13:32

Chybělo mi tam ošetřené přetékání i velkých písmen. Tak jsem to udělal takto.

// inicializace proměnných
            string ss = "cerne diry jsou tam kde buh delil nulou. Zebra zebra AABBCC";
            Console.WriteLine("Původní zpráva: {0}", ss);
            string zprava = "";
            int posun = 1; //Maximalni posun je 6!

            // cyklus projíždějící jednotlivé znaky
            foreach (char cc in ss)
            {
                int ii = (int)cc;
                ii += posun;
                // kontrola přetečení i pro velká písmena
                if (ii > (int)'z' || (ii > 'Z' && ii< 'a' ))
                    ii -= 26;
                char znak = (char)ii;
                zprava += znak;
            }

            // výpis
            Console.WriteLine("Zašifrovaná zpráva: {0}", zprava);
            Console.ReadKey();

            Console.WriteLine();
            Console.WriteLine("Desifrovani");
            string DefZprava="";

            //cyklus na desifraci
            foreach (char c2 in zprava) {
                int i2 = (int)c2;
                i2 -= posun;
                //kontrola přetečení i pro velká písmena. Funguje i s mezerama v textu.
                if ((i2 < (int)'a' && i2 > (int)'Z')||(i2 < (int)'A' && i2 > (int)'A' - posun-1))
                    i2 += 26;
                char znak2 = (char)i2;
                DefZprava += znak2;
            }
            Console.WriteLine("Desifrace: {0}", DefZprava);
            Console.ReadKey();
 
Odpovědět 7.10.2017 13:32
Avatar
Jan Kalenský:8.2.2018 22:18

Ahoj, takový malý detail. Řekl bych, že v té šifře, abychom tam měli jen písmenka, je lepší použít cyklus while, protože ta podmínka nám 26 odečte pouze jednou, což nemusí stačit.

 
Odpovědět 8.2.2018 22:18
Avatar
Petr Zajac
Člen
Avatar
Odpovídá na Jan Kalenský
Petr Zajac:24.2.2018 16:55

Mám pocit když budeš hodnotu 26 odečítat víc jak jednou (tj. na vstupu bude i něco jiného než písmenka, resp. písmenka převedená na malá), tak z kódovaného textu bude po dekódování stejným algoritmem hotový "GULÁŠ", protože nebudeš tušit kolikrát jsi vlastně těch 26 odečetl, abys dostal jako výsledek písmenko a dekódování se ti povede "napůl" :-O

 
Odpovědět 24.2.2018 16:55
Avatar
Petr Zajac
Člen
Avatar
Odpovídá na Jan Kalenský
Petr Zajac:24.2.2018 22:32

Navíc když koukám do ASCII tabulky, tak např.
32 je mezera, 33 vykřičník, 44 čárka, 46 tečka, takže když budu chtít zakódovat tyhle znaky jako písmena tak bych musel přičítat ... To samé čísla 0 je ascii 48 ... Zatímco malé "a" je 97
Když nebudu převádět vše na malé tak bych měl problém i s velkýma písmenama A - 65, Z - 90

 
Odpovědět 24.2.2018 22:32
Avatar
Andy Scheuchzer:24.4.2018 18:45

Je nějaká metoda rozlišující malá a velká písmena? Dělat to přes
string m = "abcdef…";
string v = "ABCDEF…";
a Contains() mi přijde dost pomalé a složité. :-)

Odpovědět 24.4.2018 18:45
Člověk, co si myslí, že snědl všechnu moudrost světa, i když tomu tak není.
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Andy Scheuchzer
David Čápka:24.4.2018 18:49

Podle ASCII hodnoty, což bys měl po přečtení článku vědět, přímo se to tam zmiňuje.

Odpovědět 24.4.2018 18:49
Jsem moc rád, že jsi na síti, a přeji ti top IT kariéru, ať jako zaměstnanec nebo podnikatel. Máš na to! :)
Avatar
Odpovídá na David Čápka
Andy Scheuchzer:24.4.2018 18:52

Díky. Ale otrava to bude pořád Když už programovat a lenošit, tak co nejvíc :-) mohli na to při tvorbě C# trochu myslet :-)

Odpovědět 24.4.2018 18:52
Člověk, co si myslí, že snědl všechnu moudrost světa, i když tomu tak není.
Avatar
Andy Scheuchzer:24.4.2018 18:58

Kdybych tam měl nějakou chybu, omlouvám se, dneska mi to prostě nemyslí a už je to dost dlouho, co jsem to četl.

Odpovědět 24.4.2018 18:58
Člověk, co si myslí, že snědl všechnu moudrost světa, i když tomu tak není.
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Andy Scheuchzer
David Čápka:24.4.2018 19:13

Trochu jsem to pogooglil a jsou tam statické metody na struktuře char jako Char.IsUpper("A") a podobně.

Odpovědět 24.4.2018 19:13
Jsem moc rád, že jsi na síti, a přeji ti top IT kariéru, ať jako zaměstnanec nebo podnikatel. Máš na to! :)
Avatar
Alvaro Luis
Člen
Avatar
Alvaro Luis:16.11.2018 21:25

Ahoj, tohle mi program označuje za chybu:

string s = “Ahoj”;
s[3] = “y”;
Console.Write(s);

Je tam něco špatně?

 
Odpovědět 16.11.2018 21:25
Avatar
Odpovídá na Alvaro Luis
Andy Scheuchzer:16.11.2018 21:42
  1. uvozovky
  2. přiřazuješ hodnotu do určité polohy v řetězci…četl sis to vůbec?
  3. char má okolo sebe apostrofy, ne uvozovky

David Čápka ty apostrofy by sis tam mohl opravit :-)

Odpovědět 16.11.2018 21:42
Člověk, co si myslí, že snědl všechnu moudrost světa, i když tomu tak není.
Avatar
Alvaro Luis
Člen
Avatar
Odpovídá na Andy Scheuchzer
Alvaro Luis:16.11.2018 22:05

Sorry, špatně jsem si to přečetl. (Ani s apostrofami to nejde)

 
Odpovědět 16.11.2018 22:05
Avatar
Martin Petrovaj
Překladatel
Avatar
Odpovídá na Alvaro Luis
Martin Petrovaj:17.11.2018 8:24

Vidíme, že můžeme ke znakům v řetězci přistupovat přes hranatou závorku, jako tomu je i u pole. Zklamáním může být, že znaky na dané pozici jsou v C# read-only, nemůžeme tedy napsat:

string s = "Ahoj ITnetwork";
s[1] = 'o';
Console.WriteLine(s);
Console.ReadKey();
Odpovědět  +2 17.11.2018 8:24
if (this.motto == "") { throw new NotImplementedException(); }
Avatar
Odpovídá na Alvaro Luis
Michal Štěpánek:17.11.2018 9:00

Špatně na tom je to, že NEMŮŽEŠ takto přiřazovat hodnotu a měnit znaky. Pokud chceš nahradit nějaký znak jiným, použij třeba "Replace"

Odpovědět  +1 17.11.2018 9:00
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
Odpovídá na Jan.Nygdo
Mikuláš Adamovský:18.11.2018 23:41

Díky, s (c.ToString())) to funguje.

 
Odpovědět 18.11.2018 23:41
Avatar
Jan Křížek:20.11.2018 18:41

Super článek, u cézarovy šifry jsem si přidal i mezery a funguje bez problému :)

int i = c;
//kontrola mezer
if (i == ' ')
i = ' ';
else
i += posun;
// kontrola přetečení
if (i > 'z')
i = 'a' + (i - 'z');
char znak = (char)i;
zprava += znak;

 
Odpovědět 20.11.2018 18:41
Avatar
Odpovídá na Jan Křížek
Andy Scheuchzer:21.11.2018 18:54

Příště zkus použít tlačítko na vložení kódu (druhé zleva).
A ta kontrola mezer by šla i jinak:

if (i != ' ') // Nebo i != 32
i += posun;
Odpovědět 21.11.2018 18:54
Člověk, co si myslí, že snědl všechnu moudrost světa, i když tomu tak není.
Avatar
Odpovídá na Andy Scheuchzer
Jan Křížek:21.11.2018 19:01

Tlačítko na vložení kódu tu nikde nevidím, jinak díky, opoměl jsem, že vlastně nemusím nastavovat mezeru, když už mezerou je :)

 
Odpovědět 21.11.2018 19:01
Avatar
Odpovídá na Jan Křížek
Andy Scheuchzer:21.11.2018 19:08

Tlačítko na vložení kódu tu nikde nevidím…

</> vedle smajlíka

Editováno 21.11.2018 19:08
Odpovědět  +1 21.11.2018 19:08
Člověk, co si myslí, že snědl všechnu moudrost světa, i když tomu tak není.
Avatar
kuskus265
Člen
Avatar
kuskus265:23.11.2018 20:52

Ahoj! Vysvětlil by mi prosím někdo proč je v téhle části kodu int a char v závorkách?

int i = (int)c;
i += posun;
char znak = (char)i;
zprava += znak;

Předem díky a děkuju za parádní článek, jde to skoro samo ;)

Odpovědět 23.11.2018 20:52
Bratři v triku po ulici kutálejí hořící pneumatiku
Avatar
Odpovídá na kuskus265
Andy Scheuchzer:23.11.2018 21:53

Tomu se říká přetypování. Tady to můžeš udělat díky tomu, že v charu je uložena číselná hodnota znaku (můžeš si to představit i tak, že char je číslo, ze kterého dostaneš na výstupu znak (i když nevím, jestli ti to pomůže)). Přetypováním dostaneš z charu jeho číselnou hodnotu.

Odpovědět 23.11.2018 21:53
Člověk, co si myslí, že snědl všechnu moudrost světa, i když tomu tak není.
Avatar
Patrik Pastor:29.12.2018 23:00

Proč se dávájí operátory += "plus" a "rovná se" dohromady? Předtím jsem to nikdy nedělal a příjde mi to divné, tak kdyby mi to prosím někdo vysvětlil, jaký to má význam. Díky.

 
Odpovědět 29.12.2018 23:00
Avatar
zitekv
Člen
Avatar
zitekv:29.12.2018 23:24

Kvůli zjednodušení.
Např.

celkovyPocetBodu+=5;

je úplně totožné jako

celkovyPocetBodu=celkovyPocetBodu+5;
Editováno 29.12.2018 23:25
 
Odpovědět  +3 29.12.2018 23:24
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 78 zpráv z 78.