Nejlepší odpověď
Toto je jedna z mých oblíbených otázek k diskvalifikaci C ++ odborníci .
Samozřejmě systém („PAUSE“) znamená vytvořit shell OS a nechat jej spustit příkaz „PAUSE“.
Ve skutečnosti funguje pouze ve Windows, kde to NENÍ bezpečnostní problém , protože„ PAUSE “je interní příkaz prostředí, který nevyvolá žádný externí program (pokud není samotný systémový hacker hacknut… ale než máte jiný problém)
V systému Windows to ani není velký „problém s výkonem“: obraz CMD.EXE je téměř jistě již v RAM, datový segment CMD je poměrně malý a … no … Žádáte PAUZU (neběhat tak rychle, jak můžete!)
Na systémech jiných než Windows , to nebude fungovat (nemusí existovat žádný příkaz PAUSE) a jedná se o bezpečnostní únik (někdo n vytvořte program PAUSE, který bude vykonávat jeho vlastní úkol místo vašeho).
Takže pokud se nezaměřujete na svůj vlastní jediný stroj a svůj vlastní OS, nebude to přenosné a může to být dokonce nebezpečné.
Ale problém se nyní stává „ co dělat ?“
Je fantastické vidět, jak co nejvíce Odpověď jsou… NESPRÁVNÉ , protože … nemohou fungovat!
Podívejme se proč:
Váš program cin
– má dvě celá čísla, ukazuje nějaké výsledky a … musí to počkat nebo skončit?
Předpokládejme chcete počkat: jak odpovíte na cin >> a
a cin >> b
?
Vaše zadání bude vypadat
12\n
34\n
ty MUSÍTE psát f. .ing se vrací, protože musíte opustit vstupní režim konzoly.
Nyní, cin >> a
spotřebuje „12“. Návratka zůstane ve vyrovnávací paměti.
cin >> b
spotřebuje všechny mezery (včetně návratů) až do první mezery než všechny číslice. Bude spotřebovávat „\ n34“ (a nastaveno b = 34).
Ve vstupní vyrovnávací paměti je až do… návratu. Pojďme se tedy podívat, jak všichni odborníci FAIL!
- používají
cin.get()
: ŠPATNÉ : Tím se přečte jeden znak a bude pokračovat. A ve vstupní vyrovnávací paměti je jeden znak, takže se nezastaví ! - použijte
cin.ignore()
: NESPRÁVNÉ: V vyrovnávací paměti stále existuje ten… návrat. Ignorujete to … a jdete dále. Žádná pauza .
Jak to tedy udělat?
V tomto konkrétním příkladu musíte ignorovat vše, co je ve vyrovnávací paměti, a to včetně vrácení, pak požádat o ignorování něčeho jiného:
cin.clear(); // clear an eventual "bad read" flag
cin.ignore(BIG\_NUMBER,’\n’); // ignore all remaining pending input
cin.get(); //just read one more!
BIG\_NUMBER, je … něco většího než znaky, na které můžete psát před stisknutím klávesy Enter.
Standardní způsob získání tohoto čísla je
numeric\_limits
(ne zapomenout #include
)
Takže na konci…
void pause()
{
cin.clear();
cin.ignore(numeric\_limits
cin.get();
}
být správnou funkcí pozastavit .
Ale teď mi řekněte:
Co když někdo zadá
12abcd\n
??
První čtení uvidí„ 12 “a druhé„ a … “a selže (ne číslice!). B se vůbec nečte.
Poté pause()
vymaže „špatný bit“ a zahodí abcd\n
a poté přečtěte si „1“ a šťastně ukončete.
Morální : při čtení čísel vždy zkontrolujte, zda čtení selhalo, a zahoďte případný špatný vstup:
while(!(cin >> b))
{ cin.clear(); cin.ignore(numeric\_limits
To ale vyžaduje také správu výzev atd. a vede příliš daleko od skutečného účelu.
Odpověď
Není to čisté řešení. Někteří lidé tomu mohou říkat „hack“, jiní tomu mohou říkat „náhradní řešení“.
Jak vidíte, jednou z hezkých vlastností jazyka C je jeho přenositelnost . A díky syntaxi systému („PAUSE“) tuto přenositelnost ztrácíte, protože to závisí na konzole, kterou používáte ke spuštění svého programu.
Jaká je tedy alternativa? Bohužel neexistuje dokonale čisté řešení. Viděl jsem lidi používat tuto syntaxi
std::cout << “Press any key to continue…”;
std::cin >> Some\_variable\_you\_declared\_in\_advance;
V zásadě se jedná pouze o další hackování, kdy pomocí programu pozastavíte program. Tímto způsobem však neztrácíte přenositelnost.
Jedno z nejčistších řešení, které znám, je toto (ale je velmi závislé na chuti):
void pause () {
std::cin.ignore();
}
Tímto způsobem můžete použít vlastní funkci pozastavení . V podstatě čte jeden znak a ignoruje ho, což je přesně to, čeho chcete dosáhnout. Ale jak jsem řekl, rozhodně to není nejlepší řešení, jen můj osobní favorit.