• 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

Object Storage Arubacloud
+1 głos
1,940 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,990 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 363 wizyt
0 głosów
1 odpowiedź 173 wizyt
pytanie zadane 4 maja 2017 w C i C++ przez Bish0p Obywatel (1,940 p.)
+1 głos
1 odpowiedź 870 wizyt
pytanie zadane 28 czerwca 2020 w C i C++ przez Drożdżówka Obywatel (1,870 p.)

92,693 zapytań

141,606 odpowiedzi

320,103 komentarzy

62,051 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

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!

...