přejít na obsah přejít na navigaci

Linux E X P R E S

Příspěvky Programovanie v jazyku C++: Cyklus while (1)

Programovanie v jazyku C++: Cyklus while (1)
Jardík 11. 01. 2017, 12:29:53
Odpovědět  Odkaz 
>> while (name[i] != '\0')
Tady pozor. C++ sice od C++11 garantuje, že std::string opravdu na konci řetězce nulový byte má (předtím byl takový požadavek jen na fci string::c_str()), ale nikde není zakázáno, že uprostřed stringu nemůže být taky. std::string může obsahovat nulové znaky kdekoliv! Dokonce i čtením ze std::cin použitím operátoru >> takový řetězec můžete dostat. V konzoli ho třeba nedokážete zadat, ale při přesměrování ze souboru to takový řetězec vrátí. Znak '\0' není považován za bílý znak a bude součástí vstupu. Zkuste si

#include
#include

int main()
{
std::string str;

if (std::cin >> str)
{
std::cout
Re: Programovanie v jazyku C++: Cyklus while (1)
Jardík 11. 01. 2017, 12:34:09
Odpovědět  Odkaz 
Omlouvám se, zase mi to snědlo půlku příspěvku:

Tady pozor. C++ sice od C++11 garantuje, že std::string opravdu na konci řetězce nulový byte má (předtím byl takový požadavek jen na fci string::c_str()), ale nikde není zakázáno, že uprostřed stringu nemůže být taky. std::string může obsahovat nulové znaky kdekoliv! Dokonce i čtením ze std::cin použitím operátoru >> takový řetězec můžete dostat. V konzoli ho třeba nedokážete zadat, ale při přesměrování ze souboru to takový řetězec vrátí. Znak '\0' není považován za bílý znak a bude součástí vstupu. Zkuste si:

(kód na http://pastebin.com/qU0h0auJ)

A vytvořte soubor (např. a.dat), s obsahem (hex) 61686F6A_00_6A6172646F (ahoj(NULL)jardo). Spusťte program s přesměrováním souboru na standardní vstup (./test < a.dat). Program vypíše celou sekvenci. Příklad by bylo lepší modifikovat na

while (i != name.size()) {}

A typ proměnné i samozřejmě změnit na "správný typ", kterým int není. Což je, si myslím, mnohem názornější. Popř. opravit tvrzení "Podmienka name[i] != '\0' znamená, že test bude úspešný, pokým nenarazí na ukončovací znak reťazca." a napsat tam "dokud nenarazí na první nulový byte", nebo tak něco.
Eduard Boldižár Re: Re: Programovanie v jazyku C++: Cyklus while (1)
Eduard Boldižár 11. 01. 2017, 13:41:53
Odpovědět  Odkaz 
Vďaka, zmením na:
int i = 0;
while (name[i] != NULL)
{
cout
Eduard Boldižár Re: Re: Programovanie v jazyku C++: Cyklus while (1)
Eduard Boldižár 11. 01. 2017, 13:45:25
Odpovědět  Odkaz 
Tiež mi to zle posiela odpovede. Tak ešte raz:

int i = 0;
while (name[i] != NULL)
{
cout
Eduard Boldižár Programovanie v jazyku C++: Cyklus while (1)
Eduard Boldižár 11. 01. 2017, 13:46:55
Odpovědět  Odkaz 
Ok v skratkostí, lebo niečo tu nefunguje. Lepšie while (name[i] != NULL)? Mohlo by to byť ok. i je preto integer, lebo má zaujíma index poľa.
Re: Programovanie v jazyku C++: Cyklus while (1)
Jardík 11. 01. 2017, 16:42:31
Odpovědět  Odkaz 
Né, while (name[i] != NULL) nepomůže. Poblém je, že std::string může obsahovat nulový byte, na začátku, uprostřed, nakonci, prostě kdekoliv. Ta podmínka říká "vem znak na pozici i a zkontroluj, jestli není nulový". To není stejné, jako se zeptat "je i platný index řetězce". Pokud v cyklu nehledáte první nulový byte v řetězci, ale účelem je iterovat přes všechny znaky řetězce, tak správné řešení s použitím cyklu while je porovnat index i s velikostí řetězce - např. while (i != name.size()), nebo while (i < name.size()).

Co se týče typu proměnné i, funkce std::string::size() vrací hodnotu typu std::string::size_type, což je typedef na std::size_t. To je neznaménkový číselný typ shopný pojmout, v tomto případě, hodnotu maximální délky řetězce. To s typem int zaručené nemáte a může přetéci. A přetečení znaménkového typu pak vede k nedefinovanému chování (popř. definovaného implementací při přetečení při konverzi neznaménkového typu na znaménkový). Proto správně je např.

std::size_t i = 0;
while (i < name.size())
{
// dělej něco se znakem name[i]
++i;
}

Samozřejmě použitý for-range cyklu by bylo hezčí, ale článek je o cyklu while:

for (char c : name)
{
// dělej něco se znakem c
}
Eduard Boldižár Re: Re: Programovanie v jazyku C++: Cyklus while (1)
Eduard Boldižár 11. 01. 2017, 17:37:35
Odpovědět  Odkaz 
Áno, je mi to jasne. Vďaka, zmením to.