Login musi zawierać od 3 do 12 znaków:
if (lo.length() <= 3 && lo.length() >= 12) { // błędny warunek
Musisz dostosować się do kolejności podanej w zadaniu. W przypadku rejestracji gdy podany zostanie zajęty login i błędne hasło musisz wypisać “Blad”, a nie “Login zajety”.
PS. Spróbuj skrócić trochę kod i rozdziel warstwę logiki od operacji IO.
Proszę o podpowiedź dotyczącą tego zadania, już naprawdę mam mam dosyć a jestem zbyt uparty żeby sobie odpuścić. Mój kod https://pastebin.com/hEccTrmB20 oraz jeszcze zapytam czy tu może być problem z podawaniem wartości przez cin?
cout << "register ";
cin >> registerAttemps;
Na wejściu pojawi się nieokreślona liczba zestawów zawierająca słowa register/login - dlatego powinieneś wczytać stringa i wykonać podaną operację:
int attempts;
std::string command;
while (std::cin >> command >> attempts) {
if (command == "register") {/*register*/}
else if (command == "login") {/*login*/}
}
W funkcji main masz zdublowany fragment kodu. To wszystko
Nie rozumiem pytania - cin służy do wczytywania.
Problem polega między innymi na tym, że twoje rozwiązanie nie jest poprawne nawet dla testów przykładowych z zadania, więc będzie WA.
I tu pytanie, czy Ty testujesz swoje rozwiązanie i jeżeli tak to jak?
Można testować u siebie, albo na ideone.com6 - po wklejeniu przykładowego wejścia z zadania lub swojego/innego testu do okienka stdin : https://ideone.com/LE9LpC7 [podałeś błędny - nie kompilujący się kod, poprawiłem go, tylko tak aby się kompilował].
W twoim programie, wszystkie cout << "login...., cout << "register ...
. są zbędne i są błędem. Wczytywanie danych też masz błędne.
Poprawnie możesz tak jak zaproponował @hipcia:
int main () {
// deklaracja potrzebnych zmiennych -
while (cin >> command >> attemps) {//powtarzaj, dopóki są jeszcze dane do wczytania
if (command == "register") {
//twój kod obsługujący rejestrację powtórony attemps razy
}
else {
// twój kod obsługujący logowanie powtórzony attemps razy
}
}
PS
Jeżeli wzorujesz się na stylu Stańczyka, to jego książka nie jest do nauki języka C++, a dodatkowo jest już nieco przestarzała.
Makra w C++ to spadek po języku C, i w C++14 np.: zamiast makra FOREACH:
FOREACH(it, account){
cout << it->first << " " << it->second << "\n";
}
można i jest to dużo lepiej:
for (auto i : account)
cout << i.first << ' ' << i.second << '\n';
itd.
@narbej Range-based for pojawił się w C++11. Dodałbym również referencję do deklaracji typu, ponieważ std::pair
nie można trywialnie kopiować.
Testuje swoje rozwiązania w cmd w visual studio code przy użyciu komendy a.exe, natomiast nie wiem jak dokładnie działa sędzia na spoju. Ten link który mi podałeś https://ideone.com/LE9LpC8 to w stdout sędzia otrzymuje takie wyjście?
Tak - przynajmniej starać się rezygnować.
Nie - makra, a szczególnie przedstawione w książce Algorytmika praktyczna … miały zwiększyć szybkość i wygodę kodowania, a nie szybkość samego wynikowego programu jako takiego. Oczywiście ktoś może twierdzić, że wstawienie kodu do programu [rozwijanie makr] daje szybszy kod, niż kod z wywołaniami funkcji - ale przecież są też funkcje inline…
Może nie dokładnie - w końcu, oprócz najprostszego sędziego [programu] są także czasami specjalne programy pisane przez autora zadania.
Ogólnie twój program “potraktowany” zostaje testem - przekierowanie pliku i produkuje odpowiedzi - też przekierowane zostaje do pliku. Potem już tylko porównanie pliku przygotowanego przez autora z twoim.
Czyli jeżeli testujesz u siebie w cmd - używając klawiatury, to jest to dobry sposób tylko dla prostych zadań. Dla trudniejszych, możesz przygotować plik/i testowe in.txt, oraz wynikowy out.txt [np kopijąc z zadania]
Potem:
C:\....> twój_program.exe < in.txt >twoj_out.txt [ENTER]
Poczytaj, o przekierowaniach.
Teraz pozostaje już tylko porównać [najlepiej programowo]:
c:\...> jakis_diff.exe twoj_out.txt out.txt [ENTER]
Dodatkowo możesz “opakować” [samo] testowanie w automatyczny pomiar czasu, ale wtedy musisz przygotowywać swoje większe testy, bo dla małych nie ma to sensu.
Ja używam linuxa i czasami robię/robiłem podobnie …, teraz częściej korzystam z ideone.
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:
- 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.
- 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 … - To jak z tymi makrami? Rezygnujesz?
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. - tablica:
static char AsciiSpecialCharacters[32] = {'!', '"', '#', '$', '%', '&', '*', .....
jest globalna, więc nie musisz zaznaczać, static. - można:
char AsciiSpecjal[] = "!#$%&*@..........";
- Lepiej
string AsciiSpecjal = "!#$%&*@..........";
- lub:
string AsciiSpecjal {"!#$%&*@.........."};
- Można to sprawdzić łątwiej i krócej, ale miało być krótko
- No i jeszcze te śmieci [komentarze na końcu]
- Ale się nie przejmuj, walcz, a jak coś pytaj śmiało.
Ok
Potraktuj to jako swego rodzaju prezent pod choinkę
Dotyczy to twojego starego kodu, w nowym, może część rzeczy pozmieniałeś/usunąłeś.
- // https://p…content-available-to-author-only…j.com/problems/FR_07_03/ <-- ten link jest błędny
- 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. - 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. - Jeżeli dołączasz jawnie [nie bits/stdc++.h] wiele bibliotek, to czasami warto wiedzieć, jakie są tam ukryte skarby
Np.
<cctype>
zawiera miedzy innymi isdigit(), isupper(), islower(), toupper()… itd. - 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 nazwachar specjal[]
wystarczy. Przecież, z załaczonego linku do zadania a i z samego kodu wynika, że nie chodzi tu przecież o piwo. - 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.
- …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;
}