• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

question-closed cin c++ wprowadzanie danych, blokowanie entera nowa linia

Cloud VPS
0 głosów
872 wizyt
pytanie zadane 12 grudnia 2022 w C i C++ przez piotr_domanski Bywalec (2,490 p.)
zamknięte 13 grudnia 2022 przez piotr_domanski

Witam,

Mam pytanie, jak mamy program:

#include <iostream>

using namespace std;

int a;  ///////2


int main()
{
	cout << "       TESKT  " << endl;
	cout << "       TESKT  " << endl;
	cout << "       TESKT  " << endl;
	cout << "       TESKT  " << endl;
	cout << "       TESKT  " << endl;
	cout << "       TESKT  " << endl;
	cout << "       TESKT  " << endl;
	cout << "       TESKT  " << endl;
	cout << "       TESKT  " << endl;
	
    cin >> a;
    cout << a;
}

I teraz jak mamy cin no to w konsoli podajemy wartość i program dalej działa, tylko jest pytanie. Jak klikamy enter do program nic nie robi i daje znak nowej linii i czeka na zmienną. Jak zrobić żeby tak nie było? Czyli chce zablokować przechodzenie do nowej linii enterem w cin, jak to zrobić ?

 

komentarz zamknięcia: Odpowiedź

2 odpowiedzi

–1 głos
odpowiedź 12 grudnia 2022 przez Gynvael Coldwind Nałogowiec (30,510 p.)
wybrane 13 grudnia 2022 przez piotr_domanski
 
Najlepsza

Generalnie nie da się tego łatwo zrobić, bo przejście do nowej linii jest zupełnie niezależne od cin.

Konkretniej, jak naciśniesz enter to dzieją się dwie rzeczy:

1. Program od okna terminala/konsoli stwierdza, że tzw "echo" jest włączone, więc to co "wpisał" użytkownik musi zostać wyświetlone na ekranie konsoli. Użytkownik nacisnął enter, więc na ekranie konsoli należy przejść do nowej linii.

2. Program od okna terminala/konsoli wysyła na standardowe wejście Twojego programu znak nowej linii, a cin to odbiera. Ponieważ cin spodziewa się int'a, to ignoruje biały znak i czeka dalej.

Jeśli chcesz zrobić wczytywanie zmiennej, ale ograniczone tylko do niektórych znaków (np. żeby w ogóle nie dało się wpisać liter, ani przejść do nowej linii), to musiałbyś przekonfigurować konsolę tak, żeby wyłączyć echo (żeby nic co użytkownik naciśnie się nie pojawiało) – i pamiętać ją przekonfigurować z powrotem przy wyjściu z programu – oraz w zasadzie napisać własną funkcję/klasę, która w zasadzie będzie ekwiwalentem cin (no, technicznie można spróbować wpiąć się jako "filtr" w stos wejścia używany przez cin).

Da się to zrobić, ale:

  1. To jest trochę kodu zależnego od systemu (tj. pod Windowsem i pod Linuxem robi się to trochę inaczej).
  2. Potencjalnie komplikuje to działanie przekierowań (typu: "program < dane" czy "cat dane | program"), choć jest to też do ogarnięcia.

Więc szczerze, to bym odradzał, chyba, że jest to ta konkretna rzecz, której koniecznie chcesz się nauczyć – w takim wypadku daj znać pod jaki OS to piszesz, to Ci podrzucę po czym szukać więcej informacji.

komentarz 12 grudnia 2022 przez Gynvael Coldwind Nałogowiec (30,510 p.)
Technicznie pod Linuxem można wyłączyć enter na konsoli btw, vide: stty igncr ;)

(ale jak się zapomni go włączyć, to jest zabawnie)
komentarz 12 grudnia 2022 przez piotr_domanski Bywalec (2,490 p.)

@Gynvael Coldwind, Robię to pod Windowsem

 

komentarz 12 grudnia 2022 przez Gynvael Coldwind Nałogowiec (30,510 p.)

W tym wypadku musisz iść tą dłuższą opisaną drogą.

Generalnie rzuć okiem na SetConsoleMode w WinAPI. W szczególności wyłącz konsoli echo (ENABLE_ECHO_INPUT) i buforowanie (ENABLE_LINE_INPUT). Zazwyczaj najpierw pobiera się obecny tryb konsoli (GetConsoleMode), zapamiętuje go, usuwa wspomniane wcześniej bity, i ustawia to co zostanie (SetConsoleMode).

Najlepiej znajdź sobie jakiś przykład, bo SetConsoleMode/GetConsoleMode będą potrzebowały uchwytu (HANDLE) od konsoli. W przykładzie podejrzysz sobie jak go załatwić.

To spowoduje, że nic co napiszesz na konsoli się nie pojawi (ale cin i przyjaciele nadal będą to odbierać). 

To co następne musisz zrobić, to jakąś funkcję, która zczytuje ze standardowego wejścia po kolei znaki, ale np. je filtruje, tj. zapamiętuje (i pokazuje na ekran - pamiętaj o flush!) tylko cyfry. I przy każdym naciśnięciu enter sprawdza, czy w buforze coś się już zapisało. Jeśli tak, zwraca bufor; jeśli nie, ignoruje enter (nie wypisuje go, nie dodaje do bufora).

Przy wyjściu ofc najlepiej przywrócić stare zapamiętane ustawienia konsoli.

Co więcej, najlepiej też obsłużyć Ctrl+C (patrz SetConsoleCtrlHandler) i w razie czego przywrócić w tym stare ustawienie konsoli.

Wtedy pozostanie Ci jeszcze ewentualne skonwertowanie zawartości bufora do zmiennej, etc.

komentarz 13 grudnia 2022 przez piotr_domanski Bywalec (2,490 p.)
Dzięki za podpowiedź
+1 głos
odpowiedź 12 grudnia 2022 przez VBService Ekspert (256,600 p.)

Spróbuj z

[ on-line ]

cin.ignore();
cin.get(); // Naciśnij ENTER, aby kontynuować

 

komentarz 13 grudnia 2022 przez piotr_domanski Bywalec (2,490 p.)

@VBService, dzięki ci bardzo. 

Podobne pytania

0 głosów
1 odpowiedź 256 wizyt
0 głosów
1 odpowiedź 145 wizyt
pytanie zadane 28 kwietnia 2020 w Sprzęt komputerowy przez niezalogowany
0 głosów
2 odpowiedzi 481 wizyt
pytanie zadane 26 listopada 2017 w C i C++ przez randinpa Początkujący (450 p.)

93,488 zapytań

142,421 odpowiedzi

322,772 komentarzy

62,906 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

Kursy INF.02 i INF.03
...