Jakie są wady korzystania z pauzy systemu?


Najlepsza odpowiedź

To jedno z moich ulubionych pytań dotyczących dyskwalifikacji C ++ ekspertów .

Oczywiście system („PAUSE”) oznacza utworzenie powłoki systemu operacyjnego i pozwolenie mu na wykonanie polecenia „PAUSE”.

Właściwie to działa tylko w systemie Windows, gdzie NIE jest to problem z bezpieczeństwem , ponieważ„ PAUSE ”jest wewnętrznym poleceniem powłoki, które nie wywołuje żadnego programu zewnętrznego (chyba że powłoka systemu sama została zhakowana… ale niż masz inny problem)

W systemie Windows nie jest to nawet duży „problem z wydajnością”: obraz CMD.EXE jest już prawie na pewno w pamięci RAM, segment danych CMD jest dość mały i… cóż … Prosisz o WSTRZYMANIE (nie uruchamianie tak szybko, jak to możliwe!)

W systemach innych niż okna , to nie zadziała (może nie być polecenia PAUSE) i jest to wyciek bezpieczeństwa (ktoś może n stwórz program PAUSE, aby wykonać swoje własne zadanie zamiast twojego).

Więc jeśli nie celujesz w swoją jedyną maszynę i swój jedyny system operacyjny, nie będzie to przenośne i może być nawet niebezpieczne.

Ale teraz problem wygląda następująco: „ co robić ?”

Fantastycznie jest zobaczyć, jak większość odpowiedź brzmi… ŹLE , ponieważ… nie mogą działać!

Zobaczmy, dlaczego:

Twój program cin -s dwie liczby całkowite, pokazuje wyniki i… czy musi czekać czy wyjść?

Załóżmy chcesz poczekać: jak odpowiesz na cin >> a i cin >> b?

Twoje dane wejściowe będą wyglądać następująco:

12\n

34\n

MUSISZ wpisać te f. .ing zwraca, ponieważ musisz wyjść z trybu wprowadzania konsoli.

Teraz cin >> a zużyje „12”. Zwrot pozostanie w buforze.

cin >> b zajmie wszystkie spacje (w tym zwroty) aż do pierwszej spacji, a następnie wszystkich cyfr. Zużywa „\ n34” (i ustawi b = 34).

Jest do momentu, gdy w buforze wejściowym nastąpi zwrot. Zobaczmy teraz, jak wszyscy eksperci FAIL!

  1. używają cin.get(): ŹLE : Spowoduje to odczytanie jednego znaku i kontynuację. W buforze wejściowym jest jeden znak, więc nie zatrzyma się !
  2. użyj cin.ignore(): ŹLE: W buforze nadal jest ten zwrot. Ignorujesz to… i idziesz dalej. Bez przerwy .

Jak więc to zrobić?

W tym konkretnym przykładzie musisz zignorować wszystko, co jest w buforze, aż do powrotu, a następnie poprosić o coś innego do zignorowania:

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, to… wszystko większe niż znaki, na których możesz wpisać konsoli przed naciśnięciem klawisza Enter.

Standardowy sposób uzyskania tego numeru to

numeric\_limits::max()

(don nie zapomnij #include )

A więc na koniec…

void pause()

{

cin.clear();

cin.ignore(numeric\_limits::max(),’\n’);

cin.get();

}

być odpowiednią funkcją pauzy .

Ale teraz powiedz mi:

A co, jeśli ktoś wpisze

12abcd\n

??

Pierwszy odczyt wyświetli„ 12 ”, a drugi„ a… ”i zakończy się niepowodzeniem (nie jest to cyfra!). B w ogóle nie jest czytany.

Następnie pause() wyczyści „zły bit” i odrzuci abcd\n, a następnie przeczytaj „1” i szczęśliwie zakończ.

Morał : podczas czytania liczb zawsze sprawdzaj, czy odczyt się nie powiódł i odrzuć ewentualne błędne dane wejściowe:

while(!(cin >> b))

{ cin.clear(); cin.ignore(numeric\_limits::max(),’\n’); }

Ale wymaga to również zarządzania podpowiedzi i tak dalej … i prowadzi zbyt daleko od rzeczywistego celu.

Odpowiedź

To nie jest czyste rozwiązanie. Niektórzy ludzie mogą nazywać to „hack”, a inni „obejście”.

Widzisz, jedną z fajnych właściwości języka C jest jego przenośność . A dzięki składni systemowej („PAUSE”) tracisz tę przenośność, ponieważ zależy to od konsoli używanej do uruchamiania programu.

A teraz, jakie są alternatywy? Niestety nie ma idealnie czystego rozwiązania. Widziałem ludzi używających tej składni

std::cout << “Press any key to continue…”;

std::cin >> Some\_variable\_you\_declared\_in\_advance;

Zasadniczo to tylko kolejny hack, wykorzystujący strumień do wstrzymywania programu. Ale w ten sposób nie tracisz przenośności.

Jednym z najczystszych rozwiązań, jakie znam, jest to (ale jest bardzo zależne od gustu):

void pause () {

std::cin.ignore();

}

W ten sposób możesz użyć własnej funkcji pauzy . Zasadniczo czyta jeden znak i ignoruje go, co jest dokładnie tym, co chcesz osiągnąć. Ale jak powiedziałem, z pewnością nie jest to najlepsze rozwiązanie, tylko moje ulubione rozwiązanie.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *