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

Losowanie znaków z tablicy ASCII

VPS Starter Arubacloud
+1 głos
1,858 wizyt
pytanie zadane 6 lutego 2017 w C i C++ przez CPP_Newbie Użytkownik (770 p.)

Witam,

Po dłuższej przerwie postanowiłem przypomnieć sobie C++.

Napisałem taką oto funkcję, która losuje mi znaki nie-alfanumeryczne (mam tu na myśli tylko i wyłącznie znaki ! @ # $ itp.). Funkcja działa jak najbardziej prawidłowo, ale czy da się to zrobić lepiej? W bardziej elegancki sposób?

char GetRandomChar()
{
    char array[] = {'!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/',
                    ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', '^', '_', '~'};
 
    return array[rand() % sizeof(array)];
}

 

3 odpowiedzi

0 głosów
odpowiedź 6 lutego 2017 przez Ehlert Ekspert (212,630 p.)
wybrane 6 lutego 2017
 
Najlepsza

W tablicy ASCII znaki które chcesz losować są porozbijane pomiędzy cyframi itp., więc wydaje mi się że zadeklarowanie tablicy jest całkiem zasadne. Bardziej elegancko będzie, jeśli nazwę funkcji rozpoczniesz małą literą. Co do samej nazwy czy po GetRandomChar nie znając implementacji spodziewałbyś się losowego chara nie-alfanumerycznegowink

komentarz 7 lutego 2017 przez CPP_Newbie Użytkownik (770 p.)
Racja, nazwy funkcji zaczynamy od małej litery. Moje niedopatrzenie.

Co do samej nazwy funkcji, która de facto została utworzona w ramach ćwiczeń myślę, że nie gra większej różnicy ;)
+2 głosów
odpowiedź 6 lutego 2017 przez koczurekk Gaduła (3,420 p.)
edycja 6 lutego 2017 przez koczurekk
  • Funkcja małą literą;
  • Taka tablica powinna być statyczna;
  • rand() to żart, użyj porządnego losowania z C++11.
char getRandomChar() {
	static char array[] = {'!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/',
					':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', '^', '_', '~'};
	size_t size { sizeof(array) };

	std::default_random_engine en{ std::random_device{ }() };
	std::uniform_int_distribution<size_t> dist(0, size - 1);

	return array[dist(en)];
}
komentarz 6 lutego 2017 przez criss Mędrzec (172,590 p.)

Mała poprawka odnośnie:

auto size { sizeof(array) };

auto przy size zostanie rozwinięte do std::initializer_list<std::size_t>.

Dopiero w c++17 zostało to poprawione ("poprawione" bo raczej bardziej przeszkadza niż uprzyjemnia kodowanie) na zasadzie:

auto a { sizeof(array) }; // a jest typu std::size_t
auto b = { sizeof(array) }; // b jest typu std::initializer_list<std::size_t>

Podsumowując: twój kod będzie poprawny tylko w c++17.

komentarz 6 lutego 2017 przez koczurekk Gaduła (3,420 p.)
Akurat miałem pod ręką najnowszy snapshot GCC 7 i projekt z flagą -std=c++1z, więc ten… :P Ale w sumie poprawię, nie wszyscy gonią za nowymi standardami i a nuż ktoś się załamie dostając tu dziwne błędy.
komentarz 6 lutego 2017 przez criss Mędrzec (172,590 p.)
No i super :) Tak się przyczepiłem dla zasady :D
komentarz 7 lutego 2017 przez CPP_Newbie Użytkownik (770 p.)
@koczurekk, Dlaczego tablica powinna być statyczna? W moim testowym programie nie używam żadnych klas...

Co do tej metody losowania z C++11 muszę przyznać, że pierwsze słyszę. Poczytam. Dzięki.
komentarz 7 lutego 2017 przez criss Mędrzec (172,590 p.)

Żeby nie była tworzona przy każdym wywołaniu funkcji (prawde mówiąc kompilator pewnie i tak ogarnie i nie będzie tego robił, ale kto wie). Słowo static użyte wewnątrz funkcji sprawia, że zmienna, do której się odnosi, będzie zachowywała się jak globalna z tym, że będzie "widoczna" tylko wewnątrz funkcji. Tzn. zostanie utworzona raz i będzie istnieć przez cały czas trwania programu.

W moim testowym programie nie używam żadnych klas...

To nie ma nic do rzeczy. static w c++ ma wiele znaczeń zależnie od miejsca w którym zostało użyte. 

komentarz 7 lutego 2017 przez CPP_Newbie Użytkownik (770 p.)
Ok, dzięki za szczegółowe wyjaśnienie :)
+1 głos
odpowiedź 6 lutego 2017 przez Adrian Spora Mądrala (5,100 p.)

Warto byłoby zrobić klasę typu RandomGeneratorUtils czy jakkolwiek by się miała nazywać. ta funkcja mogłaby być statyczna

Tablica znaków może być wydzielona do globalnej prywatnej stałej stałej klasowej, żeby przy każdym wywołaniu metody nie inicjalizowała się od nowa, co zajmuje czas.

Od C++ 11 używa się bardziej dokładnej funkcji generującej randomowe liczby w określonym przedziale. Może to wydawać się o wiele mniej czytelne, ale generuje lepsze liczby pod względem czystej statystyki. Poczytaj sobie o tym, tutaj.

komentarz 7 lutego 2017 przez CPP_Newbie Użytkownik (770 p.)
Poczytam o tej metodzie generowania liczb. Dzięki.

Podobne pytania

0 głosów
0 odpowiedzi 320 wizyt
0 głosów
1 odpowiedź 164 wizyt
pytanie zadane 4 maja 2017 w C i C++ przez Bish0p Obywatel (1,940 p.)
+1 głos
1 odpowiedź 795 wizyt
pytanie zadane 28 czerwca 2020 w C i C++ przez Drożdżówka Obywatel (1,870 p.)

92,451 zapytań

141,261 odpowiedzi

319,073 komentarzy

61,853 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.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...