43 / 46
Mar 2021

Teraz zacząłem testować swój kod na stronie ideone.com1 i teraz spotkałem się z takim problemem, że nie wiem dlaczego na tym serwisie niepoprawnie porównuje mi tablice znaków tzn.

  • mam funkcje is_login_contain_illegal_char w której porównuje mi znaki z loginu do tablicy znaków AsciiSpecialCharacter z tymi specjalnymi znakami, które nie powinny znajdować się w loginie.
  • następnie funkcja ta dla każdego znaku zwraca informacje, że każda litera jest znakiem specjalnym.


Tutaj jest wynik programu
tablica AsciiSpecialChar znajduje się w 28 linicie,
a funkcja is_login_contain_special_character w 128 linijce.

Dodam jeszcze, że u mnie działa na komputerze tylko mam problem na tej stronie.

Krótko:
Linia 134 wtwoim kodzie jest błędna i powinna Cię dodatkowo skłonić do przemyślenia plusów i minusów używania makr.

Pochwała:
Skupiłem się tylko na tej jednej funkcji - w linii 128 i brawo, że sam potrafiłeś to zdiagnozować.

Maleńka krytyka:

  1. Twój program jest zdecydowanie za długi i twój sposób sprawdzania - pętla zagnieźdźona w pętli może okazać się za wolny.
  2. Masz dużo inkludów - wszystkichg potrzebujesz? - ogranicz ich liczbę tylko do potrzebnych, lub zastosuj:
    #include <bits/stdc++.h> <— lista wszystkich bibliotek w STL, ale czy działa pod windows? To też nie jest to dobre ale …
  3. To jak z tymi makrami? Rezygnujesz? :wink: Masz makra na first i last, a w programie ich nie wykorzystujesz:
    cout << it.first << " " << it.second << "\n";
    zamiast:
    cout << it.ST << " " << it.ND << "\n";
    Możliwe, że jest więcej - ale nie przęglądałem dokładnie twojego kodu.
  4. tablica: static char AsciiSpecialCharacters[32] = {'!', '"', '#', '$', '%', '&', '*', ..... jest globalna, więc nie musisz zaznaczać, static.
  5. można: char AsciiSpecjal[] = "!#$%&*@..........";
  6. Lepiej string AsciiSpecjal = "!#$%&*@..........";
  7. lub: string AsciiSpecjal {"!#$%&*@.........."};
  8. Można to sprawdzić łątwiej i krócej, ale miało być krótko :wink:
  9. No i jeszcze te śmieci [komentarze na końcu]
  10. Ale się nie przejmuj, walcz, a jak coś pytaj śmiało.

Dzięki za wszystkie rady @narbej oraz @hipcia w końcu dostałem AC.
Rezygnuje z makr, ponieważ gdybym z nich nie korzystał to bym program skończył około 2 tygodnie temu.

Gratuluję!!

Brawo, cieszy mnie to.

PS
Ale zdajesz sobie sprawę, że spoj nie potrafi ocenić jakości kodu? Mógłbym ewentualnie podać Ci trochę wskazówek i trochę krytyki twojego kodu, gdybyś chciał.

Ok
Potraktuj to jako swego rodzaju prezent pod choinkę :wink:

Dotyczy to twojego starego kodu, w nowym, może część rzeczy pozmieniałeś/usunąłeś.

  1. // https://p…content-available-to-author-only…j.com/problems/FR_07_03/ <-- ten link jest błędny :wink:
  2. Nadmiar importowanych bibliotek, na zapas nie jest dobry, ale jeżeli jednak chcesz to robić, to możesz wypróbować:
    #include <bits/stdc++.h> <— włączasz wszystkie/większość bibliotek.
  3. Używanie using namespace std; + pkt.1 ułatwia pisanie prostych - krótkich kodów, ale może spowodować konflikt/y nazw. Spróbuj na przykład użyć do swojej zmiennej nazwy time.
  4. Jeżeli dołączasz jawnie [nie bits/stdc++.h] wiele bibliotek, to czasami warto wiedzieć, jakie są tam ukryte skarby :wink: Np. <cctype> zawiera miedzy innymi isdigit(), isupper(), islower(), toupper()… itd.
  5. Pisałem już wcześniej o tablicy, ale jeszcze do samej nazwy: AsciiSpecialCharacters znaki i char to prawie zamienniki, albo to samo ale w różnych językach a dodatkowo natychmiast kojarzą się z tablicą kodów ASCII. W takim razie nazwa tablicy mogłaby brzmieć np: charSpecial, ale gdy dodamy typ zmiennej, to: char charSpecjal, wydaje się nadmiarowa i że nazwa char specjal[] wystarczy. Przecież, z załaczonego linku do zadania a i z samego kodu wynika, że nie chodzi tu przecież o piwo.
  6. map<string, string> account; <-- [wyjątkowo] można zrobić globalną, w przeciwieństwie do tablicy specjal, która potrzebna jest tylko funkcji register. Można też utworzyć i zamknąć to wszystko w klasie, ale to już inna bajka.
  7. …zostało jeszcze sporo, a może i tak to nie aktualne?

Łatwiej może będzie jak po prostu wyślę Ci mój pierwszy kod na PM i sam sobie spróbujesz porównać i się czegoś nauczyć?

        if(numberOccurence == false) FOR(n, 48, 57){
            if((char)(n) == password[i]){
                numberOccurence = true;
            }
        }

Powyższy blok, jeżeli chciałbym to robić w tym samym duchu, ja zapisałbym:

FOR (n, '0', '9')
   

a naprawdę należy inaczej przeprogramować pętlę np:

dla kolejnego znaku c w haśle:
      jeżeli jest to cyfra <np isdigit(c)> to zaznacz
      else jeżeli to wielka litera .... to zaznacz
      else jeżeli mała zaznacz
      w przeciwnym wypadku, jeżeli to nie cyfra, mała ani duża litera to jest znakiem specjalnym  zaznacz to

funkcje isdigit(), isupper(), islower() są bardzo proste, można skorzystać z biblioteki <cctype> lub napisać własne, np:

bool isdigit (char c) {
   return (c >= '0' and c <= '9')
}
char tolower (char c) {
       if (isupper (c)) c += 'a' - 'A';
       return c;
}
5 months later

Witam,
Zrobiłem kod, który działa u mnie dobrze lecz po przesłaniu do sędziego wywala mi komunikat: błąd wykonania (SIGXFSZ)

Nie jestem pewien też czy dobrze zrozumiem to zadanie.

Wejście składa się z nieokreślonej ilości wierszy. W pierwszej kolejności znajduje się jeden z dwóch napisów: “register” lub “login” oznaczających rejestrację i logowanie do konta.
Po określeniu czynności widnieje niewielka ilość x działań do wykonania przez program. W kolejnych x linijkach, znajdują się login i hasło.

Co to znaczy? Mam zrobić nieskończoną pętle tak jak zrobiłem? Kompletnie nie mam pojęcia jak to zinterpretować. A jeśli program miałby przerwać pętle i zakończyć działanie to jaka reakcja ma to wywołać?

Poniżej macie mój kod:

na ideone też się coś sypie, gdy ustawiam przykładowe wejście z zadania.

PS. Były dwa tematy odnośnie tego zadania. Mam nadzieję, że dobry odkopałem.

Ja wpisałem: “register & login” i znalazłem 4 wątki zawierające te dwa słowa.

Nie wystarczy odkopać i się dokleić. Potrzeba jeszcze spróbować przeczytać, zrozumieć i wykorzystać.

Nawet więcej, najpierw to co wyżej- przeczytać, a może się okazać zbednym, zadawanie pytania.

Możliwe, że tak nie lubisz czytać, jak ja nie lubię się powtarzać czy powtarzać tego, co inni już powiedzieli :wink:

Gdy podczas linijki
cin >> whatToDo >> how_many;
nie uda sie pobrac danych z powodu EOF to te 2 zmienne beda miec ta sama wartosc czy sie zmienią? (pytanie retoryczne)

Dzięki za odpowiedź.
Okazało się, że poza tym problem miałem też parę innych błędów w kodzie.

Już wydawało mi się, że wszystko rozwiązałem bo kod działa idealnie u mnie oraz na ideone.
Niestety sędzia dalej jest dla mnie bezlitosny ale tym razem pokazuje Błędna odpowiedź .

Wie ktoś może co przeoczyłem? Sporo się naszukałem błędów w kodzie i ponad 30 danych wejściowych przetestowałem. Wydaje mi się, że wszystko jest dobrze.

9 months later

Podepne się do tego komentarza, ponieważ nie znalazłem odpowiedzi. Czy macie jakieś podpowiedzi jak stworzyć pętle która wczytuje nieokreśloną liczbę wierszy i przerywa się kiedy nic nie podamy? Jak rozumiem, na przykładzie tego zadania while(cin>>whatToDo>>how_many) nie ma prawa działać? (wiem że sędzia nie uznaje tego za błąd, pytam z ciekawości)

Skąd wniosek, że tak się nie robi?

To jest jak najbardziej prawidłowe podejście.

Sądziłem że lepiej gdyby program kończył się po wpisaniu wszystkich danych. Tan program co przytoczyłeś da się chyba zakończyć jedynie wpisując coś co nie jest liczbą w miejsce attempts. Dopisanie jakiegoś “else break;” też nie działa gdy ktoś po prostu wciśnie enter. Jeśli tak się nie programuje to ok, nie znam się :smiley:po prostu mnie to ciekawiło

To zależy jakie zachowanie programu chcesz uzyskać.
Polecam post Narbeja kilka stron wyżej, jak odpalać program tak jak to robi sprawdzarka.

Dzięki, o tym nie wiedziałem. Ale mimo wszystko jeszcze trochę pomęczę :smiley: Gdybym z jakiegoś powodu chciał taką pętle “while (cin>>cokolwiek)” która wykonuje się nieokreśloną ilość razy a przy nie wpisaniu niczego i wciśnięciu enter pętla się przerywa (nie koniecznie cały program, załóżmy że dalej chce coś jeszcze wyświetlić). Macie jakieś podpowiedzi jak takie coś zaprogramować ? :smiley: (nie wiem czy się wgl da :smiley: )

P.S chyba że naruszam zasady pisząc pod tym zadaniem to usunę. Nie jest mi to jakieś niezbędne do życia, zwykła ciekawość

Teg o o co pytasz, nie da się zaprogramować, za pomocą pętli:

while (cin >> cokolwiek)

Dlaczego? Dlatego, że cin ignoruje białe znaki, a ENTER, jest właśnie jednym z nich [białym znakiem].
Można to oczywiście zrobić [zaprogramować] w inny sposób, np używając getchar (), getline itd, ale skoro:

(nie jestem i raczej nie będę informatykiem/programistą :smiley: )

zaspokój w takim razie proszę moją zwykłą ciekawość, jeżeli możesz. Co robisz lub co robi PŚk [Politechnika Świętkokrzyska] w twoim profilu? :wink: I czemu masz już prawi 50 rozwiązanych zadań na spoju - tylko hobby?

O taką odpowiedź mi chodziło, dzięki :wink: (o getline() wiedziałem ale chciałem wiedzieć czy da się cin, bo działało lepiej do momentu zakończenia :smiley: Też mnie trochę zmyliło że wczytywanie z pliku w ten sam sposób while (inFile>>cokolwiek) działało (wychodził z pętli po wczytaniu wszystkiego), a gdzieś czytałem że cin jest klasą pochodną ifstream więc spodziewałem się podobnego działania :man_shrugging:(chyba że coś pomieszałem)) . Zaspokajając twoją ciekawość: studiuje automatyke. Na drugie pytanie sam nie znam odpowiedzi :joy: zawsze interesowało mnie wiele ale nie programowanie, a teraz postanowiłem się sprawdzić i w tym, zobaczymy na czym się skończy :smiley:

3 months later

Czy coś jest nie tak ze sprawdzarką? Rozwiązanie w pythonie przechodzi, a w C nie