Beste antwoord
Dit is een van mijn favoriete vragen om C ++ te diskwalificeren experts .
Natuurlijk betekent systeem (“PAUSE”) een OS-shell maken en het een “PAUSE” -commando laten uitvoeren.
Eigenlijk is dat werkt alleen op Windows, waar het GEEN veiligheidsprobleem is , aangezien” PAUSE “een shell-intern commando is dat geen extern programma aanroept (tenzij je systeemshell zelf gehackt is … maar dan heb je nog een ander probleem)
Op Windows is het zelfs geen groot “prestatieprobleem”: het beeld van CMD.EXE zit vrijwel zeker al in het RAM, het CMD-gegevenssegment is vrij klein en … nou ja … Je vraagt om PAUZE (niet om zo snel mogelijk te rennen!)
Op systemen andere dan Windows , dit zal niet werken (er is mogelijk geen PAUSE-commando) en is een beveiligingslek (iemand kan n maak een PAUSE-programma om zijn eigen taak uit te voeren in plaats van de jouwe).
Dus tenzij je je richt op je eigen enige machine en je eigen enige besturingssysteem, zal dat niet draagbaar zijn en kan het zelfs gevaarlijk zijn.
Maar het probleem wordt nu “ wat te doen in plaats daarvan?”
Het is fantastisch om te zien hoe de meeste van de antwoord zijn … FOUT , omdat … ze kunnen niet werken!
Laten we eens kijken waarom:
Uw programma cin
-s twee gehele getallen, wat resultaten laat zien en … moet het wachten of afsluiten?
Laten we aannemen je wilt wachten: hoe antwoord je op de cin >> a
en cin >> b
?
Je invoer zal eruit zien als
12\n
34\n
je MOET die f. .ing keert terug, omdat je de console-invoermodus moet verlaten.
Nu zal cin >> a
“12” verbruiken. Het resultaat zal in de buffer blijven.
cin >> b
zal alle spaties (inclusief retouren) verbruiken tot de eerste niet-spatie, dan alle cijfers. Het zal “\ n34” verbruiken (en b = 34).
Er is tot een laatste terugkeer in de invoerbuffer. Laten we nu eens kijken hoe alle experts FAIL!
-
cin.get()
gebruiken: FOUT : dit leest één teken en gaat verder. En er is één teken in de invoerbuffer, dus het zal niet pauzeren ! - gebruik
cin.ignore()
: FOUT: Er is nog steeds die laatste terugkeer in de buffer. Je negeert het… en gaat verder. Geen pauze .
Dus hoe moet je het maken?
In dit specifieke voorbeeld alles moet negeren dat zich in de buffer bevindt tot en met de terugkeer, en vraag dan om iets anders om te negeren:
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, is … alles dat groter is dan de tekens waarop je kunt typen de console voordat je op enter drukt.
De standaardmanier om dit nummer te krijgen is
numeric\_limits
(don t vergeet #include
)
Dus op het einde …
void pause()
{
cin.clear();
cin.ignore(numeric\_limits
cin.get();
}
zal een goede pauze -functie zijn.
Maar vertel me nu:
Wat als iemand typt
12abcd\n
??
De eerste keer lezen zal” 12 “zien en de tweede” a … “en zal mislukken (geen cijfer!). B wordt helemaal niet gelezen.
Dan zal pause()
de “slechte bit” wissen en abcd\n
verwijderen, en vervolgens lees “1” en sluit vrolijk af.
Moreel : controleer bij het lezen van getallen altijd of het lezen niet mislukte en gooi eventuele slechte invoer weg:
while(!(cin >> b))
{ cin.clear(); cin.ignore(numeric\_limits
Maar dit vereist ook beheer van prompts enzovoort … en leidt te ver weg van het werkelijke doel.
Antwoord
Het is geen schone oplossing. Sommige mensen noemen het “hack”, sommige mensen noemen het “tijdelijke oplossing”.
Zie je, een van de leuke eigenschappen van C-taal is de draagbaarheid . En met de systeemsyntaxis (“PAUSE”) verliest u deze overdraagbaarheid, omdat dit afhangt van de console die u gebruikt om uw programma uit te voeren.
Nu, wat zijn de alternatieven? Helaas is er geen perfect schone oplossing. Ik heb mensen deze syntaxis zien gebruiken
std::cout << “Press any key to continue…”;
std::cin >> Some\_variable\_you\_declared\_in\_advance;
In feite is dit gewoon weer een hack die stream gebruikt om je programma te pauzeren. Maar u verliest op deze manier uw draagbaarheid niet.
Een van de schoonste oplossingen die ik ken is deze (maar hij is erg smaakafhankelijk):
void pause () {
std::cin.ignore();
}
Op deze manier kunt u uw eigen pauzefunctie gebruiken . Het leest in feite één teken en negeert het, en dat is precies wat u wilt bereiken. Maar zoals ik al zei, het is zeker niet de beste oplossing, alleen mijn persoonlijke favoriet.