Efekty dynamicznych podpowiedzi w C


(fedora24x) #1

Potrzebuje zrobić linijke do wprowadzania tekstu w C (w konsoli) jak moge uzyskac efekt dynamicznie wprowadzanego tekstu, chodzi mi o takie dymki (wiersze poniżej) coś na wzór sugestii dla podawanego tekstu?


(Rolek0) #2

W standardzie C nie ma czegoś takiego jak “konsola”, ani tym bardziej “dymki”.

Żeby bezpośrednio operować na konsoli musisz używać specyficznych metod dla danego systemu albo użyć biblioteki np. ncurses/pdcurses.


(stasinek) #3

Nie wprowadzaj go w BŁĄD. 

https://www.cs.cf.ac.uk/Dave/C/node18.html

Jasne że jest do niej dostęp i nie potrzeba skomplikowanych bibliotek. W istocie pod maską obsługa jej polega na otwieraniu “plików”  standardowymi funkcjami IO (open, write, read) przy czym to jądro systemu decyduje jak rozpoznaje nazwy, odczyty i zapisy to w jaki sposób interpretuje znaki specjalne ‘\n’ , ‘\r’ - powrót do pierwszego znaku linii, ‘\t’ 

printf("%c[2K", 27); wykasowanie linii powrót do poprzedniej

Własnie znaki specjalne dają wystarczającą formę do stworzenia “dymków” bo większośc konsol jest ze sobą zgodna. http://www.climagic.org/mirrors/VT100_Escape_Codes.html Z konsolą jak z przeglądarką internetową niby HTML nie kontroluje przegladarki, ale jednak zwykły strumień znaków wystarczy żeby kontrolować co wyświetla. 

Aby zrobić to czego oczekujesz “dymków”, progress barów, guziczków itp. efektów wystarczy abyś wykorzystał znaki powrotu do początku linii \r, \b i powrotu do poprzedniej linii i to Ci umożliwi wyświetlanie dymka ponad polem wpisywania. Ponadto wyświetlenie tego co juz zostało znak po znaku wpisane, z uwzglednieniem kasowania ich beckspace:

key = getch(); if (key == 127 || key == 8) { ...  

Przy odrobinie ręcznej dłubaniny można nawet system “okienkowy” stworzyć w konsoli. Na dobrą sprawe przypominający właśnie działanie HTML - tzn. czytelne i zapisywalne w edytorze tagi zamiast niezbyt wygodnych znaków specjalnych. Jeśli przygotować odpowiedni tekst z formularzem i wrzucić go to printf całe “okna” z treścią można wyświetlać. Aby podmieniać znaki w “template” można użyć funkcji strstr zastępując np. tekst: “$imie_____” tekstem "Jasio      " itd. wypełnić i wyświetlić, to już zalezy od inwencji. Można z powodzeniem zrobić nawet przeglądarkę internetową w C, serio. Otwierasz socket serwera na porcie 80, wysyłasz tekst “GET… troche tekstowych parametrów” odbierasz “tekst”, wyświetlasz po swojemu np. w konsoli ot… cała magia :)

Konsol można zrobić ile chcesz, między procesami porozumienwać się w ten sposób - na tej bazie powstał koncept rury która pomija tworzenie pliku fizycznie na dysku. Sprzęt w systemie Linux jest “przeniesiony” w przestrzeń nazw systemu plików więc w Linuxie czyste C daje dużo większe możliwości. W teorii można otworzyć dysk jako wielki plik RAW. Jeśli przekierować konsole do czarnej dziury /dev/null nie pozostanie ślad, jeśli otworzyć wejście /dev/random otrzymasz randomowe wartości wygenerowane przez system. Podobnie ze wszystkim z np. /dev/tty0-7. Poza tym mechanizmem pozostaje wywoływanie przerwań systemowych (tupanie nóżką)

Koniec końców C wszystko obsługuje przez IO w trybie pliku. Jakby nie patrzeć konsola dla C istnieje ale jest obiektem czysto umownym. By nie obsługiwać jej na “plikach” bezpośrednio, stworzono funkcje pomocnicze takie jak getch, print, printf, scanf. Które pod koniec formatowania otwierają standardowe wyjście i wrzucają tam treść. 

Konsoli analogicznie do tworzenia plików nie trzeba wyświetlać można przekierować do plików(logów) albo można stworzyć własny interfejs konsolowy w programie okienkowym i wyświetlać/interpretować po swojemu. Można posłużyć się systemowym API i wyświetlić “gotowca” który będzie śledził zawartość standardowego wejścia, wyjścia, error dla danego procesu. Bo fakt za wyświetlenie okna odpowiada API systemowe. IDE na podstawie opcji projektu zmusza linkera do wstawienia CreateConsole przed wywołaniem main i cała magia konsol. 

Aby nad tym oknem mieć kontrole wymagane jest stosowne do systemu API. Zmiana rozmiaru, wpływ na czcionke itd. Ale wcale nie potrzeba tego okna wyświetlać. Gdyby była potrzeba to i trójwymiarową konsole w OpenGL można stworzyć, albo konsole głosową dla niewidomych ;) 

Ja zamiast odwoływać sie do CreateConsole i tworzyć dwa osobne programy konsolowy i graficzny preferuje hybryde. Uniwersalny console_handler w C którym zależnie od kompilacji czy konsolowej czy GUI, każde printf przekierowuje stosownie do wyboru Windows albo w okienko graficzne Qt/VCL. Daje to kontrole nad zapisywaniem informacji, automatycznym pojawianiem okienek zamiast konsolowych pól do wprowadzania danych, przejrzeniem historii itd. Proteza tymczasowa ale działa. Przed wpisaniem do mojej konsoli znaku końca linii, sprawdzam jaki tekst w tej linii przyleciał i na tej podstawie graficzne okno zmienia treść. Np. progress bar, np. nazwa pliku, np. błąd. Jeśli czegoś nie przewidziałem pozostaje zostaje podejrzenie w oknie z tekstem. I to wszystko bez zmian w niskopoziomowym silniku aplikacji, bez rozdzielania ich systemem “klient serwer”. Poza drukowaniem tekstu istnieje dodatkowy systemem callbacków dla zdarzeń. Tak czy owak. Jeden projekt konsolowy, jedno #define i kompiluje wersje konsolowe do testów silnika albo user friendly do testów GUI. Zanim wpadłem na to że konsola twoim przyjacielem powstał program czysto graficzny. Ale to jest jak wiezienie z którego później trudno uciec.