tag:blogger.com,1999:blog-5111379941038471672024-03-13T21:05:55.444+09:00謎のC言語ブログ<a href="http://hatenaclang.blogspot.com/2011/03/c.html">はじめに</a>、<a href="http://akigamyl.bbs.fc2.com/">掲示板</a>、<a href="http://hatenaclang.blogspot.com/2011/03/c_12.html">標準関数一覧</a>、<a href="http://hatenaclang.blogspot.com/2011/04/thema.html">テーマ別分類</a>
<br>ラベルから目的の例題を探せます(検索の際には「C言語」の文字は必要ありません)。GAMIhttp://www.blogger.com/profile/10115765732273048987noreply@blogger.comBlogger182125tag:blogger.com,1999:blog-511137994103847167.post-3781527450847919132021-07-31T23:06:00.002+09:002021-07-31T23:06:46.026+09:00動画ファイルの一覧を作成し、ファイルサイズ順に並べ替えて出力するスクリプト容量の大きな動画ファイルに ffmpeg で再エンコードを掛けたい場合等に、ファイルの一覧を作成して容量順にソートするスクリプトです。
カレントフォルダ以下の動画ファイルを並べ替えて出力します(対応する拡張子は @mvext で指定)。
#!/usr/bin/perl -w
use strict;
use Cwd;
use Getopt::Std;
use File::Basename;
my @mvext = ('mp4','avi','mkv','wmv');
my $cwd = getcwd();
my %opts; getopts("hl:", \%opts) or die usage();
my $limit = 0;
for my $opt (keys %opts) {
if ( $opt eq 'h') { usage(); }
elsif ($opt GAMIhttp://www.blogger.com/profile/10115765732273048987noreply@blogger.com0tag:blogger.com,1999:blog-511137994103847167.post-28118196599450254742021-07-17T00:11:00.006+09:002021-07-17T00:14:53.393+09:00VLC用のプレイリストを作成するスクリプト色んな環境で利用できる VLC ですが、サブフォルダの展開が行われず、ランダム再生しようとしてもトップのフォルダしか再生されないと言うことが多々あります。
サブフォルダを一つ一つリストからクリックして展開すると利用可能になりますが、あまりにも使い勝手が悪いので、その手間を省く方法を考えてみました。
以下のスクリプトを実行すると、XSPF と言う XML形式のプレイリストが出力されます。
出力される内容をファイル保存し、VLC で再生するとサブフォルダの内容もはじめから展開された形で再生が可能になります。
#!/usr/bin/perl -w
use strict;
use Cwd;
use URI::Escape;
my @mvext = ('mp4','avi','mkv','wmv');
my @movies = ();
my $cwd = getcwd();
# 引数がGAMIhttp://www.blogger.com/profile/10115765732273048987noreply@blogger.com0tag:blogger.com,1999:blog-511137994103847167.post-16185583915316187392021-07-09T21:19:00.003+09:002021-07-09T21:20:32.776+09:00自宅PCのグローバルIPアドレスをメール送信するスクリプト自宅PCのSFTP等にアクセスしたいとき、自宅サーバーのアドレスを外部サーバー等を利用せずに定期的に知らせてくれるスクリプトを書いてみました。
Postfix で Gmail へ送信できる環境を整えておき(OSX postfix 等参照)、グローバルIPが変更される度にメールを送信してくれるスクリプトになります。
スクリプトを実行すれば curl が http://ifconfig.co/ にアクセスしてIPアドレスを取得し、その結果をコンフィグファイルに書き出します。
その結果が変更されればメールを送信します。
crontab に登録しておけばアドレスが変更されても自宅PCにアクセスすることができます(まだ未検証ですが)。
#!/usr/bin/perl -w
use strict;
my $mail = "#####\@gmail.com";
my $GAMIhttp://www.blogger.com/profile/10115765732273048987noreply@blogger.com0tag:blogger.com,1999:blog-511137994103847167.post-44665384989985977892020-01-03T23:57:00.001+09:002020-01-04T00:07:11.483+09:00libcurl を用いた画像のPOST(multipart/form-data or raw 形式)libcurl を用いて画像をPOST(multipart/form-data or raw 形式)する例題です。
multipart/form-data にて Base64化された送信(CURL_PostFormMedia)と、バイナリ形式での送信(CURL_PostRawMedia)をそれぞれ切り替えて利用することが出来ます。
サーバー側の実装例も合わせて記載(CGIを実行する際の引数で受信する形式を切替)。
multipart/form-data で送信する際には、ファイルが埋め込まれたフィールド名(<input type="file" name="file" />)を送受信側で合わせる必要があります。
サーバー側の form 内に、<input type="file" name="file"> と記載されている場合には name で指定されている "GAMIhttp://www.blogger.com/profile/10115765732273048987noreply@blogger.com0tag:blogger.com,1999:blog-511137994103847167.post-35650283579126676522019-01-01T00:35:00.001+09:002019-01-01T01:09:11.503+09:00フォントを指定して文字列画像の作成(libgd):絵文字対応フォントを指定して文字列画像の作成(libgd)する例題です。
文字列中の絵文字を、twemoji にて用意されている絵文字画像で置き換えながら描画していきます。
指定されたフォントで割り当てられていない文字や絵文字は「?」で表示されます。
また、UTF-8 文字列を UNICODE化(32bit)し、Freetype により一文字ずつ描画可能な文字かどうかを判定しています(FT_Get_Char_Index)。
ビルドするには libgd/freetype2/libpng が必要となります。
実行ファイルと同じパスに NotoSansCJKjp-Regular.otf と、twemoji からダウンロードした絵文字画像を配置してください。
#include
#include
#include
#include
#include
#include
#include
GAMIhttp://www.blogger.com/profile/10115765732273048987noreply@blogger.com0tag:blogger.com,1999:blog-511137994103847167.post-1971519946619136682018-12-29T12:33:00.002+09:002019-01-01T00:41:30.442+09:00UTF-8文字列をUNICODE化し、絵文字判別UTF-8で指定された文字列をUNICODE化し(32bit)、絵文字かどうかを判定する例題です。
絵文字かどうかの議論は色々あるかと思いますが、twemoji 内に格納されている絵文字を基準としています。
→ emoji-png フォルダに png として保存し、ファイルを検索してチェック
絵文字かどうかを判定した後は元のUTF-8に戻し、標準出力へ出力しています。
絵文字に対応していないフォントを用いているUI等では、絵文字が表示されない場合がありますので、絵文字の部分は twemoji 内の png で置き換えて表示したりすることができます。
#include
#include
#include
#include // uint*_t
#include
//-----------------------------------------------GAMIhttp://www.blogger.com/profile/10115765732273048987noreply@blogger.com0tag:blogger.com,1999:blog-511137994103847167.post-39900943528859391622018-09-23T04:14:00.002+09:002018-09-25T23:31:32.108+09:00Broadcast Wave Format に対応した WAVE 音声の読み込みBroadcast Wave Format に対応した WAVE 音声の読み込みの例題です。
Broadcast Wave Format (BWF) は、マイクロソフトのWAV音声ファイルフォーマットの拡張であり、映画やテレビで使われているノンリニアデジタルレコーダーの録音フォーマットとしてよく使われている。
WAVEファイルの読込み/再生 での例題で WAVEファイルを読み込んだ際、ヘッダ部分がうまく取得できないWAVEファイルが存在していました。
中身を見ると、フォーマット用のチャンク部分に「fmt 」ではなく、「bext」と記載されているファイル形式のファイルでした。
PCMの音声データ部分のチャンクは「data」から始まり、PCM音声部分の抜き取りは正常に動作していたのですが、元の音声の形式がどのようなものかを正常に取得できていないので困ることになります。
なので、この「GAMIhttp://www.blogger.com/profile/10115765732273048987noreply@blogger.com0tag:blogger.com,1999:blog-511137994103847167.post-41255523512074966072017-09-02T22:12:00.001+09:002017-09-02T22:15:24.174+09:00libcurl による連続取得における排他処理HTTPS コネクション時の libcurl による連続GET にて HTTPS への GET リクエストを行う際、curl ハンドラを初期化せずに利用した方が高速にダウンロードされると言う例題を記載しましたが、別のスレッドでタイミングがバラバラに GET したい場合、排他処理にて安全性を確保するための例題です。
libcurl 自体はスレッドセーフ化されているので、curl_easy_init にて毎回ハンドラを初期化し利用すれば何の問題もなく別のスレッドで GET リクエストを行えますが、同じハンドラを使いまわしたい場合には同じタイミングで同じハンドラが利用されないように排他処理を行っておく必要があります(今回のような特別な用途でないかぎりは全く必要のない例題です)。
pthread_mutex_lock にて排他処理を行っているので、GET リクエストが並列化されるわけではないGAMIhttp://www.blogger.com/profile/10115765732273048987noreply@blogger.com0tag:blogger.com,1999:blog-511137994103847167.post-73598779273982941962017-08-14T14:00:00.000+09:002017-08-15T09:33:44.037+09:00libcurl-multi による並行GETリクエストlibcurl-multi による並行GETリクエストを行う例題です。
例題では複数のURLを指定し並列にGETリクエストを行い、その結果を用意した char 型のバッファ内に格納しています。
HTTPS で連続取得を行う場合にはこちらで試した方法の方が高速な場合があります。
#include
#include
#include
#include
#include
#include
//----------------------------------------------------------------------------------------------------
#define HTTP_BUFFER (65536*2)
struct HttpInfo { int status; char url[256], buffer[GAMIhttp://www.blogger.com/profile/10115765732273048987noreply@blogger.com0tag:blogger.com,1999:blog-511137994103847167.post-70138706688782620592017-08-11T20:11:00.001+09:002017-08-12T23:23:48.267+09:00HTTPS コネクション時の libcurl による連続GETリクエストの高速化の検討HTTPS コネクション時の libcurl による連続GETリクエストを高速化するための検証用の例題です。
libcurl による GET 取得時の高速化手段として以下のサイトでまとめられています。
https://moz.com/devblog/high-performance-libcurl-tips
(c-ares/PowerDNS 等により DNSのリスポンスを良くするとか libcurl-multi による並列処理化等、上記サイトには書かれていませんが TCP FAST OPEN に対応しているサーバーであれば libcurl からオプションを指定して利用できます)
一方、HTTPS でのリクエストでは証明書の検証等で、単純なデータやり取り以外の部分で内部的に処理が食われてしまうことがあります。
下記の例題では HTTPS にてデータ取得を行うサイトが信頼のあるサイトでGAMIhttp://www.blogger.com/profile/10115765732273048987noreply@blogger.com0tag:blogger.com,1999:blog-511137994103847167.post-78499168618562145582017-07-15T10:34:00.002+09:002017-07-17T23:30:18.438+09:00GDによるグラフ描画(最小二乗法による直線近似)libgd によるグラフ描画の例題です(最小二乗法による直線近似)。
文字列画像の作成 にて用意したフォントを用い、sin関数により生成したデータのグラフを作成しています。
graphInit 関数にてグラフ作成時のオプションを指定していますが、グラフの横幅(graw)、縦幅(grah)、余白(padding)、グラフ描画オプション(DrawType BASE_UNDER:最小値を基準としてグラフを作成する BASE_ORIGIN:原点を基準としてグラフを作成する)等を指定できます。
genData の type にて最大値や最小値が異なるデータを生成していますが、グラフは枠内に収まるよう自動的にスケーリングして描画され、縦横軸のラベルもそれに応じて描画されます。
データのグラフ化のついでに、最小二乗法による直線近似も行っています。グラフ化に用いるデータから傾き、切片を計算し、近似GAMIhttp://www.blogger.com/profile/10115765732273048987noreply@blogger.com0tag:blogger.com,1999:blog-511137994103847167.post-83864359842365054632017-07-02T20:39:00.001+09:002017-07-02T20:49:55.881+09:00フォントを指定して文字列画像の作成(libgd)libgd を利用しフォントを指定して文字列画像を作成する例題です。
OpenType のフォントが Google から配布されていますのでそれをダウンロードし、実行ファイルと同じフォルダ内に保存します(例として NotoSerifCJKjp-[weight].otf を利用)。
libgd のインストールはこのような感じです(OSX、freetype や libjpeg/libpng も予めインストール)。
% ./configure --prefix=/usr/local --with-png=/usr/local --with-freetype=/usr/local
% make
例題では、余計な余白や画像サイズを手入力で計算する必要がないように、予め文字列の描画に必要な領域を計算しておき画像のサイズを決定しています。
複数行にて表示していますが、行間を広げたい場合等にはGAMIhttp://www.blogger.com/profile/10115765732273048987noreply@blogger.com0tag:blogger.com,1999:blog-511137994103847167.post-47746007745004970242017-06-22T00:16:00.002+09:002017-06-22T00:17:37.648+09:00libasound によりPCM音声録音libasound によるPCM音声録音の例題です。
Linux や Raspberry にてコマンドラインからマイクに接続し音声を WAVE ファイルとして保存します。
libasound がインストールされていない場合、下記のコマンドによりインストールしてください。
% apt-get install libasound2-dev
また、例題のような自分で録音用のコーディングをしなくてもツール群が提供されています。
% sudo apt-get install alsa-utils
alsa-utils に含まれる arecord コマンドにて録音、aplay コマンドにより再生が可能です。
この arecord コマンドにより、PC にマイク機器が接続されているかを確認することができます。
% arecord -l
**** ハードウェアデバイス CAPTURE のGAMIhttp://www.blogger.com/profile/10115765732273048987noreply@blogger.com0tag:blogger.com,1999:blog-511137994103847167.post-13331485871247698782017-06-21T12:23:00.002+09:002017-06-21T12:25:00.722+09:00WAVE/PCM 音声の生成WAVE/PCM 音声を生成する例題です。
WAVE 音声に関して以前まとめたものはこちら(WAVEファイルの読込み/再生)
WAVE 音声のフォーマットに合わせてヘッダを書き込み(2ch, 44100Hz)、sin 波形の振幅を徐々に大きくした音声を生成しています。
#include
#include
static void write_word(FILE* fp, unsigned long value, unsigned size)
{
for ( ; size; --size, value >>= 8 ) { char v = static_cast(value & 0xFF); fwrite(&v,1,1,fp); }
}
int main(int argc, char* argv[])
{
FILE* fp = fopen("sinwave.wav"GAMIhttp://www.blogger.com/profile/10115765732273048987noreply@blogger.com0tag:blogger.com,1999:blog-511137994103847167.post-43804390066042186992017-06-21T00:47:00.004+09:002017-06-21T00:52:25.967+09:00ローカルネットワークから NetBios 名の取得ローカルネットワークから Windows および Samba でのファイル共有を行っているマシンの NetBios 名を取得する例題です。
例題では、自機のIPアドレスからスキャンを行うIPアドレスの範囲を設定し、それぞれのアドレスに対して NetBios 名を取得しています。
NetBios 名を解決するための手順を省略している部分もあるため上手く取得できない場合もありますが、Windows マシンでは概ね正常に動作しています(Samba のネームサーバー/nbmd に対して取得できない場合も)。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//--------------------------------GAMIhttp://www.blogger.com/profile/10115765732273048987noreply@blogger.com0tag:blogger.com,1999:blog-511137994103847167.post-53026206479534977202017-06-20T17:11:00.003+09:002017-06-21T00:54:03.638+09:00CGI に対応した HTTP リクエストによるファイル保存CGI に対応した HTTP リクエストによるファイル保存の例題です。
ソケット通信を用いて HTTP リクエストを行う場合、レスポンスヘッダに含まれる Content-Length が 0 となり正しく本文が取得できない場合があります(libcurl 等を用いるとその辺の処理は自動的に行ってくれます)。
Apache サーバーに index.html 等のファイルを直接要求した場合にはそのようなことはありませんが、リクエストしたページが CGI で構成されている場合にそういう状況が発生します。
CGI はファイルの読み出しやページの生成の都合に応じて、逐次転送を行いますので、Content-Length の代わりにこれから送信するバイト数を16進数字にて送信しその本文を送信した後、転送が終われば 0 の文字列を送信します。
CGIによるファイル送信の流れ
レスポンスヘッダ
9bd9GAMIhttp://www.blogger.com/profile/10115765732273048987noreply@blogger.com0tag:blogger.com,1999:blog-511137994103847167.post-83443954397736652372017-06-20T13:52:00.000+09:002017-06-20T13:52:42.449+09:00libjpeg によるカラーバーの作成libjpeg により JPEG 画像でのカラーバーを作成する例題です。
apt-get や brew(OSX)等により libjpeg をインストール後、libjpeg へのリンク(-ljpeg)を追加しビルドしてください。
例題では、128x32 のサイズの RGB画像が作成され、JPEGファイルとして保存されます。
HDDの使用率等を示すようなカラーバーが作成されます(例題では50%の使用率)。
#include
#include
#include
int main(int argc, char* argv[])
{
struct jpeg_error_mgr jerr;
struct jpeg_compress_struct cinfo;
cinfo.err = jpeg_std_error(&jerr); // エラーハンドラにデフォルト値GAMIhttp://www.blogger.com/profile/10115765732273048987noreply@blogger.com0tag:blogger.com,1999:blog-511137994103847167.post-3323607977756633032017-06-20T11:04:00.000+09:002017-06-21T00:54:26.426+09:00NTPサーバーからの時刻取得NTPサーバーから時刻を取得し表示する例題です。
NTPサーバー(time.asia.apple.com)は適宜変更してください。
#include
#include
#include
#include
#include
#include
#include
#include
//----------------------------------------------------------------------------------------------------
#define JAN_1970 0x83aa7e80 // 2208988800 1970 - 1900 in seconds
#define NTP_PORT (123)
#define NTPFRAC(x) (4294*(x) + ((1981*(x))>>11))
//--GAMIhttp://www.blogger.com/profile/10115765732273048987noreply@blogger.com0tag:blogger.com,1999:blog-511137994103847167.post-92036213666945725702017-06-20T04:26:00.000+09:002017-06-20T04:36:54.341+09:00レーベンシュタイン距離により名前の類似度順に並べ替えレーベンシュタイン距離により名前の類似度順に並べ替え表示する例題です。
例題では、「佐藤浩市」と言う名前に対する類似度をレーベンシュタイン距離により計算し、その距離に応じて qsort により近い順に並べ替えて表示しています。
#include
#include
#include
struct PLabel { int id, dis; char name[128]; };
// ソート関数
static int name_sort(const void* a, const void* b)
{
if ( ((PLabel*)a)->dis < ((PLabel*)b)->dis ) return -1;
else if ( ((PLabel*)a)->dis == ((PLabel*)b)->dis ) return 0;
return 1;
}
//GAMIhttp://www.blogger.com/profile/10115765732273048987noreply@blogger.com0tag:blogger.com,1999:blog-511137994103847167.post-13602640021733747012017-06-20T04:00:00.002+09:002017-06-20T04:31:03.863+09:00UNIX名前付きパイプによるスレッド間通信FIFO(名前付きパイプ)によりスレッドやプロセス間の通信を行う例題です。
FIFO は UNIX 上ではファイルとして作成することができますので、スレッドやプロセス間等様々な状況において簡単に通信を行うことができます。
例題ではソースを分割して用意すると分かりにくくなりますので、main 関数から読み込み用のスレッドに対して文字列を送信すると言う形になっています。
#include
#include
#include
#include
#include
#include
#include
#include
#include
void* readFIFO(void* argv)
{
char* path = (char*)argv;
char buf[BUFSIZ];
int fd, len;
if ( (fd=openGAMIhttp://www.blogger.com/profile/10115765732273048987noreply@blogger.com0tag:blogger.com,1999:blog-511137994103847167.post-13102560887587278072017-06-17T13:50:00.003+09:002017-06-20T04:30:54.653+09:00重複なしの乱数発生(初期値の指定)/Javascript・Perl版重複なしの乱数発生 を修正し、100〜200までの値を発生する等、初期値を指定した乱数を発生させる例題です(初期値100、個数100での乱数発生)。
エクセルや既存のサイトのCGI等でそのようなことは可能かもしれませんが、5000個、10000個ともなってくるとスクリプトや従来の重複なしの方法では相当に時間がかかってしまうので、コマンドラインツールとして利用することが主な目的になります。
また、Javascript・Perl版も用意しています。
10000個の乱数発生では、Cで作成した場合には0.1秒、Perlで作成した場合には5秒近くと速度は圧倒的に違いますが、CGI等で利用するための参考として。
randtable.cpp
#include
#include
#include
#include
// 0〜max までの乱数の発生(int型)
static int GAMIhttp://www.blogger.com/profile/10115765732273048987noreply@blogger.com0tag:blogger.com,1999:blog-511137994103847167.post-52951775039317677182017-06-02T19:35:00.001+09:002017-06-17T01:39:52.219+09:00strtok_r によるネスト化されたトークンの切り出しstrtok_r によるネスト化されたトークンの切り出しの例題です。
テキストファイルを読み込み、単語ごとにハッシュ表を作成し、出現する頻度を表示する例題も兼ねています。
strtok 関数はスレッドセーフ化されておらず、再入可能(リエントラント)な利用には向いていません。
strtok 自体が最初の引数で与えられた文字列を変更してしまうためや、内部で確保された文字列の中身を変更してトークンとして切り出しているためです。
while 内に while 文で strtok を呼び出したり、別のスレッドで strtok を呼び出した場合、最後に呼び出された strtok により内部の文字列が変更され、思い通りの結果が得られないと言う状況が発生します。
また、ある関数で strtok を使っていて、その結果から別の関数を呼び出した場合、ソース上からは見えない状況で正しい結果が得られないと言うGAMIhttp://www.blogger.com/profile/10115765732273048987noreply@blogger.com0tag:blogger.com,1999:blog-511137994103847167.post-26087073544959735182015-10-10T00:03:00.000+09:002015-10-10T00:27:46.617+09:00複数バイトにまたがるビット演算ADTS形式のAACファイルのヘッダ解析等において、複数バイトにまたがるビット列を解析したい場合があります。
今回はそのような場合におけるビット列の読み込み・書き込みの例題を示します。
bitbuffer.h/bitbuffer.cpp がビット演算を行うヘッダ及びソース。
sample.cpp にて ADTS形式のヘッダを生成するための例を用意しています(AAC LC 形式のヘッダ)。
また、生成した ADTS形式のヘッダの内容を解析して構造体に読み込み直すための例(ParseAdtsHeader 関数)も用意しています。
適当なADTS形式のAACファイルの解析を行う場合には、syncword 等により ADTSヘッダの先頭位置を検索し、ParseAdtsHeader 関数によりヘッダを読みこめば AACファイル内のチャンネル数やサンプリングレート等の情報を読み込むことができます。
GAMIhttp://www.blogger.com/profile/10115765732273048987noreply@blogger.com0tag:blogger.com,1999:blog-511137994103847167.post-83741829234642238232014-12-20T08:15:00.001+09:002017-06-21T00:55:06.961+09:00libcurl/liboauth を用いて Twitter API からの結果を取得libcurl/liboauth を用いて Twitter API からの結果を取得する例題です。
他サイトで散々説明されているとは思いますが、簡単な手順は以下になります。
・libcurl の準備
Twitter API 1.1 からは、https 接続が必要となるため、libcurl には ssl 対応のものが必要となります。
・liboauth の準備
Twitter API との認証を行うためのライブラリです。
・Twitter API の利用開始
TwitterDevelopers にてアプリケーション登録を行い、コンシューマーキーやアクセストークンを取得します。
#include
#include
#include
#include "oauth.h"
#include
int main(int argc, char* argv[])
{
GAMIhttp://www.blogger.com/profile/10115765732273048987noreply@blogger.com0tag:blogger.com,1999:blog-511137994103847167.post-78420093605274613982014-11-24T12:01:00.003+09:002014-11-24T13:01:07.813+09:00行数を指定してテキストファイルの内容を反転表示行数を指定し、テキストファイルの内容を反転表示する例題です(1行毎の内容は反転しない)。
行の先頭ファイル位置を記憶するための配列を準備し、ファイル全体を読み込んで先頭位置を記憶後、順番に読み込んで出力を行っています。
表示する行数を指定するため、配列の内容は上書きして循環的に利用しています。
#include
#include
#include
#include
#include
static void printReverse(int nLines, const char* fileName)
{
int fd = open(fileName, O_RDONLY);
if ( fd == -1 ) return;
char buffer[BUFSIZ];
int maxLines = (nLines + 1), GAMIhttp://www.blogger.com/profile/10115765732273048987noreply@blogger.com0