Jak zablokować wciśnięcie klawisza?

Dyskusje na dowolny temat.

Re: Jak zablokować wciśnięcie klawisza?

Nowy postprzez Cyfrowy Baron » środa, 20 stycznia 2010, 00:20

Wszystko się zgadza, nie możemy jednak dojść do porozumienia, gdyż Ty nie przeczytałeś uważnie mojego pierwszego postu, a ja w tym poście popełniłem drobny ale pociągający za sobą poważne konsekwencje błąd:

Zablokowane zostaną litery b B e E, gdyż wielkość liter nie gra tutaj roli. Rozmiar zmiennej keyString został ustawiony na 3, gdyż tylko trzy litery ma przechowywać, ustal ten rozmiar w zależności od liczby blokowanych liter, czyli rozmiar = liczba blokowanych liter + 1;


Zwracam uwagę na ten fragment: rozmiar = liczba blokowanych liter + 1;

Rozmiar tablicy musi być o jeden większy od liczby wprowadzonych znaków.

CodeGuard nie wskazał żadnych błędów gdyż testy przeprowadzałem z jednym blokowanym znakiem przy rozmiarze tablicy 3, więc wszystko było prawidłowo.
Po wprowadzeniu dwóch blokowanych znaków i rozmiarze tablicy 3, CodeGuard wskazuje błąd:

► 

W pierwszym wątku podałem nieprawidłowy rozmiar tablicy, gdyż testy przeprowadzałem na jednym blokowanym znaku, potem tworząc wątek dodałem drugi znak bo w swoim pytaniu kurczez podał dwa znaki, więc chciałem być dokładny i dodałem drugi znak, zapominając o zmianie rozmiaru tablicy.

Byłem niedokładny i to wywołało te zgrzyty, być może wcześniej bym to zauważył, gdyby nie nieco ironiczna wypowiedź polymorphism. Prawidłowe rozwiązanie do mojego pierwszego wątku powinno oczywiście wyglądać tak:

Kod: Zaznacz cały
void __fastcall TForm1::Memo1KeyPress(TObject *Sender, wchar_t &Key)
{
   wchar_t keyString[4];
   keyString[0] = Key;
   wcscpy(&keyString[1], L"b");
   wcscpy(&keyString[2], L"e");

   for(int i = 1; i < sizeof(keyString)/2; i++)
   {
    if(Key == keyString[i]) Key = NULL;
   }
}




W pliku pomocy do C++Builder 2010 znalazłem taki oto przykład pod hasłem OnKeyPress - C++ Example:

Kod: Zaznacz cały
void __fastcall TForm1::FormKeyPress(TObject *Sender, char &Key)
{
   wchar_t keyString[25];
   keyString[0] = Key;
   wcscpy(&keyString[1], L" Was છૐ૨૪ Pressed");
   TMsgDlgButtons() << mbOK;
   MessageDlg(String(keyString), TMsgDlgType(mtInformation), TMsgDlgButtons() << mbOK, 0);
}


Jak widać autorzy środowiska nie zgłaszają zastrzeżeń do tej funkcji o ile prawidłowo się jej używa...



Nie tylko, ten błąd będzie występował wszędzie. Oczywiście konsekwencje mogą być różne, np. żadne, jak u Ciebie, lub takie jak u kurczeza - psucie stosu, czyli poważna sprawa. Witold wyjaśnił gdzie leży błąd.


Nie mogę się zgodzić z tym stwierdzeniem. Funkcja nie wywołuje żadnych błędów, działa poprawnie. Błąd wynika z nieprawidłowego zastosowania funkcji przez programistę.
Oczywiście w funkcji kryje się potencjalne niebezpieczeństwo przepełnienia bufora, gdy liczba znaków wprowadzanych do zmiennej jest równa rozmiarowi bufora, podczas gdy powinna być o jeden większa, tak jak to miało miejsce w przypadku podanego przeze mnie kodu jak i w przypadku kurczez, gdzie błąd nie wynikał bezpośrednio z funkcji, lecz ze sposobu w jaki została użyta. Gdyby jednak wszyscy przeczytali i przywiązali większą wagę do tego co napisałem w pierwszym wątku w tym poście, że rozmiar tablicy musi być o jeden większy od liczby blokowanych znaków, nie byłoby tej całej dyskusji. Tutaj muszę przyznać, że później ja sam nie zastosowałem się do własnych zaleceń. Jakoś mi to umknęło. :?
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    NieznanyNieznana

Re: Jak zablokować wciśnięcie klawisza?

Nowy postprzez polymorphism » środa, 20 stycznia 2010, 11:12

Cyfrowy Baron napisał(a):Nie mogę się zgodzić z tym stwierdzeniem. Funkcja nie wywołuje żadnych błędów, działa poprawnie. Błąd wynika z nieprawidłowego zastosowania funkcji przez programistę.

No chwileczkę, przecież to Ty twierdziłeś, że strcpy źle działa, nie ja:
    Cyfrowy Baron napisał(a):Gdybym zastosował od razu rozwiązanie podobne do Twojego, problem zostałby szybciej rozwiązany, ale wtedy nie wyszłoby np. to, że funkcja strcpy w środowisku Turbo C++ nieprawidłowo przekazuje wartości, a tak kurczez już wie, że jeżeli kiedyś będzie potrzebował użyć funkcji strcpy to zamiast niej trzeba użyć strncpy
Z tego co napisałeś wynika zupełnie coś innego ;)

Cyfrowy Baron napisał(a):Gdyby jednak wszyscy przeczytali i przywiązali większą wagę do tego co napisałem w pierwszym wątku w tym poście, że rozmiar tablicy musi być o jeden większy od liczby blokowanych znaków, nie byłoby tej całej dyskusji.

A co to zmienia? Co z tego, że opiszesz coś poprawnie, jeśli kod będzie zawierał błędy? Początkujący nie będzie analizował Twoich słów, tylko skopiuje Twój kod i wklei go u siebie. Ba, on nawet kodu nie będzie jakoś szczególnie analizował...
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    NieznanyNieznana

Re: Jak zablokować wciśnięcie klawisza?

Nowy postprzez Cyfrowy Baron » środa, 20 stycznia 2010, 11:25

No chwileczkę, przecież to Ty twierdziłeś, że strcpy źle działa, nie ja:


Odniosłem się w ten sposób do stwierdzenia kurczez, że u niego w Turbo C++ to nie działa prawidłowo, ale sądziłem, że zastosował się do mich zaleceń i ustawił prawidłowo rozmiar bufora, czyli +1.

Pozwól, że przytoczę Twoje własne słowa:

Nie tylko, ten błąd będzie występował wszędzie.


Jak już wyjaśniłem, nie wszędzie i nie zawsze.



A co to zmienia? Co z tego, że opiszesz coś poprawnie, jeśli kod będzie zawierał błędy? Początkujący nie będzie analizował Twoich słów, tylko skopiuje Twój kod i wklei go u siebie. Ba, on nawet kodu nie będzie jakoś szczególnie analizował...


Nie pisałem sobie tego wszystkiego ot tak by sobie pisać, skoro to napisałem to po to by inni to czytali. Początkujący powinie szczególnie zwracać uwagę na takie opisy i analizować kod, jeżeli chcą się czegoś nauczyć. Nawet początkujący, gdyby zwrócił uwagę na opis byłby wskazać błąd, a tymczasem nawet Ty nie wychwyciłeś tego błędu, wychwycił go Witold.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    NieznanyNieznana

Re: Jak zablokować wciśnięcie klawisza?

Nowy postprzez polymorphism » środa, 20 stycznia 2010, 12:25

Odniosłem się w ten sposób do stwierdzenia kurczez, że u niego w Turbo C++ to nie działa prawidłowo, ale sądziłem, że zastosował się do mich zaleceń i ustawił prawidłowo rozmiar bufora, czyli +1.

No widzisz, jest dokładnie tak, jak napisałem w poprzednim poście. Dlatego apeluję o uwagę przy pisaniu kodów.

Jak już wyjaśniłem, nie wszędzie i nie zawsze.

Błąd będzie wszędzie, tylko jak pisałem, nie zawsze będzie się on objawiał segfault'em lub innymi niekorzystnymi efektami. Co z tego że u Ciebie działa, jeśli to samo nie działa u Witolda i kurczeza? Poprawny kod powinien działać na każdym kompilatorze.

a tymczasem nawet Ty nie wychwyciłeś tego błędu, wychwycił go Witold.

No jak nie? ;) Zobacz, gdzie jest mój post, a gdzie Witolda. Witold wytłumaczył, na czym ten błąd polega. Ja tego nie zrobiłem, bo chciałem, żebyś to Ty go znalazł (żeby było w zgodzie z zasadą, że człowiek uczy się na (swoich) błędach).
Ostatnio edytowano środa, 20 stycznia 2010, 12:29 przez polymorphism, łącznie edytowano 1 raz
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    NieznanyNieznana

Re: Jak zablokować wciśnięcie klawisza?

Nowy postprzez Cyfrowy Baron » środa, 20 stycznia 2010, 12:29

Błąd będzie wszędzie, tylko jak pisałem, nie zawsze będzie się on objawiał segfault'em lub innymi błędami.


Jeżeli rozmiar bufora zostanie ustawiony prawidłowo, nie będzie błędu w działaniu funkcji i o tym cały czas się sprzeczam. Funkcja działa prawidłowo o ile zostanie prawidłowo użyta, sama w sobie nie jest błędna.



No jak nie? ;) Zobacz, gdzie jest mój post, a gdzie Witolda.


Fakt nie doczytałem do końca Twojego wątku.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    NieznanyNieznana

Re: Jak zablokować wciśnięcie klawisza?

Nowy postprzez polymorphism » środa, 20 stycznia 2010, 12:30

<nic>
Ostatnio edytowano środa, 20 stycznia 2010, 13:16 przez polymorphism, łącznie edytowano 1 raz
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    NieznanyNieznana

Re: Jak zablokować wciśnięcie klawisza?

Nowy postprzez Witold » środa, 20 stycznia 2010, 12:39

Cyfrowy Baron napisał(a):Wszystko się zgadza, nie możemy jednak dojść do porozumienia, gdyż Ty nie przeczytałeś uważnie mojego pierwszego postu, a ja w tym poście popełniłem drobny ale pociągający za sobą poważne konsekwencje błąd:


Całkiem bezpodstawny zarzut. Szkoda że musimy się tym zajmować, to naprawdę mało ważne...

W pierwszym poście najpierw jest kod, potem to wyżej zacytowane wyjaśnienie („Zablokowane zostaną litery…”) , wobec czego pozwolę sobie analizować razem.

Zwracam uwagę na ten fragment: rozmiar = liczba blokowanych liter + 1;


Co jest w kodzie ?

wchar_t keyString[3];
keyString[0] = Key;
wcscpy(&keyString[1], L"b");
wcscpy(&keyString[2], L"e");


Blokujesz 2 litery (b,e) potem (ł,ś) tablica ustawiona jest na 3 elementy (zgodnie z „rozmiar = liczba blokowanych liter + 1;”). Tego nie rozumiem „keyString[0] = Key;”, a że to nie pomyłka świadczą argumenty pętli for (zaczynasz iterować od 1 nie 0).

W pierwszym wątku podałem nieprawidłowy rozmiar tablicy, gdyż testy przeprowadzałem na jednym blokowanym znaku, potem tworząc wątek dodałem drugi znak bo w swoim pytaniu kurczez podał dwa znaki, więc chciałem być dokładny i dodałem drugi znak, zapominając o zmianie rozmiaru tablicy.


Gdyby tak było tablica miała by rozmiar 2 ( = 1 (liczba blokowanych liter) + 1), a ma rozmiar 3.

Rozmiar tablicy musi być o jeden większy od liczby wprowadzonych znaków.


No chyba we wszystkich wcześniejszych kodach tak miałeś podane, a w kodzie „prawidłowe rozwiązanie do mojego pierwszego wątku powinno oczywiście wyglądać tak:”, blokujesz 2 znaki a tablica ma rozmiar 4 (wchar_t keyString[4]) - niezgodnie z tą zasadą. Co więcej nie korzystałeś z strchr (wcschr), tylko z pętli for więc tablica mogła mieć rozmiar równy ilości blokowanych liter, nie musiałeś troszczyć się o miejsce dla 0 (koniec cstring’a).
Avatar użytkownika
Witold
Konstrukcjonista
Konstrukcjonista
 
Posty: 223
Dołączył(a): piątek, 29 sierpnia 2008, 10:53
Podziękował : 1
Otrzymał podziękowań: 14
Kompilator: bcb6, Turbo C++ Explorer
    NieznanyNieznana

Re: Jak zablokować wciśnięcie klawisza?

Nowy postprzez Cyfrowy Baron » środa, 20 stycznia 2010, 12:49

Gdyby tak było tablica miała by rozmiar 2 ( = 1 (liczba blokowanych liter) + 1), a ma rozmiar 3.


Nieprawda 2 byłoby źle, dla jednej blokowanej litery potrzeba tablicy o rozmiarze trzy:

keyString[0] = Key;
keyString[1] = blokowany znak;
keyString[2] = 0;

Przeprowadzając test na jednym blokowanym znaku wogóle nie używałem pętli, tylko warunku:

if(Key == keyString[1]) Key = NULL;

Pętle dopisałem sobie potem odpowiadając na post i wtedy popełniłem błąd, gdyż skupiłem się tylko na zmiennej char i rozmiar mi pasował:

keyString[0] = Key;
keyString[1] = blokowany znak 1;
keyString[2] = blokowany znak 2;

Nie wziąłem pod uwagę funkcji strcpy. Gdybym przetestował ten kod przed napisaniem wątku, wtedy wyskoczyłby błąd i bym go wyłapał.

Tego nie rozumiem „keyString[0] = Key;”, a że to nie pomyłka świadczą argumenty pętli for (zaczynasz iterować od 1 nie 0).
[...]
Co więcej nie korzystałeś z strchr (wcschr), tylko z pętli for więc tablica mogła mieć rozmiar równy ilości blokowanych liter, nie musiałeś troszczyć się o miejsce dla 0 (koniec cstring’a).


Pominąłem keyString[0], gdyż zawierał wartość wciśniętego klawisza, a w warunku, w pętli była zbędna, dlatego zacząłem sprawdzanie od keyString[1] do sizeof(KeyString). Popełniłem błąd, ale jak wspomniałem skupiłem się na zmiennej char, zapominając zupełnie o funkcji strcpy. Gdybym ten kod testował to ustawiłbym rozmiar keyString na 4 a pętla kończyła by się na sizeof(keyString) - 1.
Dlateczego wpisałem do keyString[0] wartość Key, w tym kodzie do niczego. Początkowo miałem pewien pomysł, ale z niego zrezygnowałem, chciałem po prostu porównywać keyString[0] == keyString[1], ale doszedłem do wniosku, że po co to komplikować i porównałem z Key, a tamto pozostało.
Jak łatwo się domyślić, przy nawale obowiązków pisałem odpowiedź szybko i stąd tyle błędów.

Jak widzisz Sherlock'u Twoja analiza jest błędna.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    NieznanyNieznana

Re: Jak zablokować wciśnięcie klawisza?

Nowy postprzez Witold » środa, 20 stycznia 2010, 13:12

Cyfrowy Baron napisał(a):Nieprawda 2 byłoby źle, dla jednej blokowanej litery potrzeba tablicy o rozmiarze trzy:


To nie ja tak twierdziłem, może jeszcze pamiętasz: „rozmiar = liczba blokowanych liter + 1;”
Ile jest 1 (jedna litera) + 1 ? trzy ?

Cyfrowy Baron napisał(a):keyString[0] = Key;
keyString[1] = blokowany znak;
keyString[2] = 0;

Gdzie w tym sens ? Tablica dla jednego znaku ?

Cyfrowy Baron napisał(a):chciałem po prostu porównywać keyString[0] == keyString[1]


Mając zmienną Key ?

Cyfrowy Baron napisał(a):Nie wziąłem pod uwagę funkcji strcpy. Gdybym przetestował ten kod przed napisaniem wątku, wtedy wyskoczyłby błąd i bym go wyłapał.


Uważasz że jesteś tak dobry że możesz dawać posty bez testowania ich ? Jeżeli się pomylisz jaki będzie z nich pożytek. Wyciągniecie wniosku że strcpy nie działa w Turbo C++?

Cyfrowy Baron napisał(a):Jak widzisz Sherlock'u Twoja analiza jest błędna.


konkretnie w czym ?
Sherlock'u ? pamiętasz ten kawałek o traktowaniu z góry ?
Avatar użytkownika
Witold
Konstrukcjonista
Konstrukcjonista
 
Posty: 223
Dołączył(a): piątek, 29 sierpnia 2008, 10:53
Podziękował : 1
Otrzymał podziękowań: 14
Kompilator: bcb6, Turbo C++ Explorer
    NieznanyNieznana

Re: Jak zablokować wciśnięcie klawisza?

Nowy postprzez Cyfrowy Baron » środa, 20 stycznia 2010, 13:16

konkretnie w czym ?

Konkretnie we wszystkim co przedstawiłeś w swoim przedostatnim wątku.
Sherlock'u ? pamiętasz ten kawałek o traktowaniu z góry ?

Jak widzisz do ciebie to też da się odnieść przeczytaj swój przedostatni wątek.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    NieznanyNieznana

Re: Jak zablokować wciśnięcie klawisza?

Nowy postprzez Witold » środa, 20 stycznia 2010, 13:26

Cyfrowy Baron napisał(a):
konkretnie w czym ?

Konkretnie we wszystkim co przedstawiłeś w swoim przedostatnim wątku.
Sherlock'u ? pamiętasz ten kawałek o traktowaniu z góry ?

Jak widzisz do ciebie to też da się odnieść przeczytaj swój przedostatni wątek.


Bądź tak miły i daj linka\cytat, żeby była jasność o co Ci chodzi (dotyczący mojej analizy i traktowania z góry).
Avatar użytkownika
Witold
Konstrukcjonista
Konstrukcjonista
 
Posty: 223
Dołączył(a): piątek, 29 sierpnia 2008, 10:53
Podziękował : 1
Otrzymał podziękowań: 14
Kompilator: bcb6, Turbo C++ Explorer
    NieznanyNieznana

Poprzednia strona

  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Dyskusje

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 1 gość