C言語には、整数型の乱数を生成してくれる便利なrand()関数が存在します。
これを使ってWeb上で使われている#FFCC00などのような16進Webカラーをランダムで生成してみます。
とは言っても、いきなり#FFCC00のような文字列を16進数で生成できるわけではないので、今回はrand()関数とprintf関数の書式設定を併用してWebカラーを生成してみます。
考え方
1.rand()関数を使って0~255までの範囲の乱数をRGBそれぞれに対して生成する
2.printf関数の%x書式設定を使って生成した乱数を16進数で表示する
とりあえずプログラミングしてみる
乱数生成の基本に関して詳しく知りたい方は以下を参考にしてください。
まずRGBの3種類の乱数を0~255までの範囲で生成します。
int r, g, b; srand((unsigned)time(NULL)); r = rand() % 256; g = rand() %256; b = rand() % 256;
次にそれぞれ16進数に変換して表示します。printf関数の書式指定子に%Xまたは%xを使えば簡単です。
printf("#%02X%02X%02X\n", r, g, b);
ソースコード全体
#include <stdio.h> #include <stdlib.h> #include <time.h> int main(void) { int r, g, b; srand((unsigned int)time(NULL)); r = rand() % 256; g = rand() %256; b = rand() % 256; printf("#%02X%02X%02X\n", r, g, b); return 0; }
実行例
#0FED88
生成したランダムカラーを文字列として格納する
printf関数で出力しただけだと使いまわしが出来ません。
「#FFCC00」のような文字列としてchar型配列に格納できるようプログラムを改良してみます。
sprintf関数を使うとprintfの書式で出力した通りの文字列としてchar型配列に保存してくれます。
sprintf(書き込み先の配列, “書式”, 変数1, 変数2,…);
#include <stdio.h> #include <stdlib.h> #include <time.h> int main(void) { int r, g, b; char rgb[8]; srand((unsigned int)time(NULL)); r = rand() % 256; g = rand() %256; b = rand() % 256; sprintf(rgb, "#%02X%02X%02X", r, g, b); printf("保存した文字列: %s\n", rgb); return 0; }
実はsprintfはバッファオーバーフローを発生させやすい関数の1つです。
例えば、char rgb[8];として宣言していたとしても、書き込むときに
sprintf(rgb, "*********%02X%02X%02X", r, g, b);
などと8文字以上(ヌル文字を考慮すれば7文字)の文字列を書き込んでもコンパイルエラーとはならず、実行時に配列の要素数以上の文字列を書き込んでしまうことになります。これがバッファオーバーフローです。
きちんと作成するには、snprintf関数を使って指定したバイト数以上は配列に格納できない仕様にしておくべきです。
snprintf(書き込み先の配列, 書き込むバイト数, “書式”, 変数1, 変数2,…);
今回の場合ならこんな感じになります。
#include <stdio.h> #include <stdlib.h> #include <time.h> int main(void) { int r, g, b; char rgb[8]; srand((unsigned int)time(NULL)); r = rand() % 256; g = rand() %256; b = rand() % 256; snprintf(rgb, 8,"#%02X%02X%02X", r, g, b); printf("保存した文字列: %s\n", rgb); return 0; }
こうすることで配列要素数の8文字以上は書き込めないようになり安全です。
以上、C言語でWebカラーをランダム生成するでした。
コメント