2017年6月2日金曜日
strtok_r によるネスト化されたトークンの切り出し
strtok_r によるネスト化されたトークンの切り出しの例題です。
テキストファイルを読み込み、単語ごとにハッシュ表を作成し、出現する頻度を表示する例題も兼ねています。
strtok 関数はスレッドセーフ化されておらず、再入可能(リエントラント)な利用には向いていません。
strtok 自体が最初の引数で与えられた文字列を変更してしまうためや、内部で確保された文字列の中身を変更してトークンとして切り出しているためです。
while 内に while 文で strtok を呼び出したり、別のスレッドで strtok を呼び出した場合、最後に呼び出された strtok により内部の文字列が変更され、思い通りの結果が得られないと言う状況が発生します。
また、ある関数で strtok を使っていて、その結果から別の関数を呼び出した場合、ソース上からは見えない状況で正しい結果が得られないと言うことにもなり得ます。
strtok_r はこのような状況においても現在扱っている文字列の処理に影響が及ぶことはありません。
以下のソースでは、テキストファイルの内容を全てメモリ内に格納した後、strtok_r にて改行(\n)とスペース( )により単語を抜き出し、ハッシュテーブルへの登録や頻度のカウントを行っています。
loadHashBAD 関数は strtok により処理を行うもので、思い通りの結果が得られていないことが分かります(一行目の単語しか抽出できない)。
loadHash 関数にて strtok_r を利用することにより全ての行の単語が抽出されます。 実行結果(strtok を使用した場合:loadHashBAD) 実行結果(strtok_r を使用した場合:loadHash) file.txt の内容
strtok 関数はスレッドセーフ化されておらず、再入可能(リエントラント)な利用には向いていません。
strtok 自体が最初の引数で与えられた文字列を変更してしまうためや、内部で確保された文字列の中身を変更してトークンとして切り出しているためです。
while 内に while 文で strtok を呼び出したり、別のスレッドで strtok を呼び出した場合、最後に呼び出された strtok により内部の文字列が変更され、思い通りの結果が得られないと言う状況が発生します。
また、ある関数で strtok を使っていて、その結果から別の関数を呼び出した場合、ソース上からは見えない状況で正しい結果が得られないと言うことにもなり得ます。
strtok_r はこのような状況においても現在扱っている文字列の処理に影響が及ぶことはありません。
以下のソースでは、テキストファイルの内容を全てメモリ内に格納した後、strtok_r にて改行(\n)とスペース( )により単語を抜き出し、ハッシュテーブルへの登録や頻度のカウントを行っています。
loadHashBAD 関数は strtok により処理を行うもので、思い通りの結果が得られていないことが分かります(一行目の単語しか抽出できない)。
loadHash 関数にて strtok_r を利用することにより全ての行の単語が抽出されます。 実行結果(strtok を使用した場合:loadHashBAD) 実行結果(strtok_r を使用した場合:loadHash) file.txt の内容
2015年10月10日土曜日
複数バイトにまたがるビット演算
ADTS形式のAACファイルのヘッダ解析等において、複数バイトにまたがるビット列を解析したい場合があります。
今回はそのような場合におけるビット列の読み込み・書き込みの例題を示します。
今回はそのような場合におけるビット列の読み込み・書き込みの例題を示します。
bitbuffer.h/bitbuffer.cpp がビット演算を行うヘッダ及びソース。
sample.cpp にて ADTS形式のヘッダを生成するための例を用意しています(AAC LC 形式のヘッダ)。
また、生成した ADTS形式のヘッダの内容を解析して構造体に読み込み直すための例(ParseAdtsHeader 関数)も用意しています。
適当なADTS形式のAACファイルの解析を行う場合には、syncword 等により ADTSヘッダの先頭位置を検索し、ParseAdtsHeader 関数によりヘッダを読みこめば AACファイル内のチャンネル数やサンプリングレート等の情報を読み込むことができます。
bitbuffer.cpp では、InitiBitBuffer により解析に用いるバッファや長さを指定し、その中のビットを徐々にシフトしながら読み込み・書き込みを行っています。
指定された長さ以上の読み込みや書き込みを行おうとした際には、何も起きずにエラーが返ります。
sample.cpp bitbuffer.h bitbuffer.cpp 実行結果
2014年12月20日土曜日
libcurl/liboauth を用いて Twitter API からの結果を取得
libcurl/liboauth を用いて Twitter API からの結果を取得する例題です。・libcurl の準備
Twitter API 1.1 からは、https 接続が必要となるため、libcurl には ssl 対応のものが必要となります。
・liboauth の準備
Twitter API との認証を行うためのライブラリです。
・Twitter API の利用開始
TwitterDevelopers にてアプリケーション登録を行い、コンシューマーキーやアクセストークンを取得します。
他サイトで散々説明されているとは思いますが、簡単な手順は以下になります。
実行すると、result.txt に JSON 形式で API からの応答結果が保存されます。
細かい制御を必要としないのであれば、URL に直接引数を指定してツイートの検索結果を取得したり、現在のトレンドデータを取得することができます。
例題中の URL では、「大泉洋」と言うキーワードでツイートを一件だけ取得したり、日本の現在のトレンドとなっているデータを取得しています。
2014年11月24日月曜日
行数を指定してテキストファイルの内容を反転表示
行数を指定し、テキストファイルの内容を反転表示する例題です(1行毎の内容は反転しない)。
行の先頭ファイル位置を記憶するための配列を準備し、ファイル全体を読み込んで先頭位置を記憶後、順番に読み込んで出力を行っています。
表示する行数を指定するため、配列の内容は上書きして循環的に利用しています。 実行結果
行の先頭ファイル位置を記憶するための配列を準備し、ファイル全体を読み込んで先頭位置を記憶後、順番に読み込んで出力を行っています。
表示する行数を指定するため、配列の内容は上書きして循環的に利用しています。 実行結果
2014年10月13日月曜日
libcurl によるGMAIL送信
libcurl を使って GMAIL アカウントを用いてメールを送信する例題です。
元の例題はこちらを参照 例題では、送信先、受信先のアドレスを同じものとし、Date や Message-ID 等のヘッダを自動的に作成するようにしています。
正常にメールを送信するためには、CURLOPT_USERNAME, CURLOPT_PASSWORD の値を自分のアカウントに合わせて編集して下さい。 実行結果
元の例題はこちらを参照 例題では、送信先、受信先のアドレスを同じものとし、Date や Message-ID 等のヘッダを自動的に作成するようにしています。
正常にメールを送信するためには、CURLOPT_USERNAME, CURLOPT_PASSWORD の値を自分のアカウントに合わせて編集して下さい。 実行結果
2014年9月30日火曜日
getopt による引数の解釈
getopt により引数を解釈します。
getopt_long 関数を利用することにより、長いオプション (2 つのダッシュ "--" で始まるオプション) を受け付け、オプションに関係ない引数も受け付けるようにしています(non-option arg: として表示される)。 実行結果
getopt_long 関数を利用することにより、長いオプション (2 つのダッシュ "--" で始まるオプション) を受け付け、オプションに関係ない引数も受け付けるようにしています(non-option arg: として表示される)。 実行結果
2014年9月7日日曜日
行数を指定してファイルを逆順に取得
行数を指定してファイルを逆順に読み取り、その結果を取得し表示する例題です。
逆順に取得する方法は従来であれば、
・ファイルの内容を一行ずつ読み取る
・その結果を配列として保存
・配列の結果を逆から取得する
という手順となります。 その際、確保するメモリの量が行数分+最終的な結果の分となるためメモリの確保に困りますが、以下の例題では一時的に確保するメモリの代わりにファイルポインタの位置、行の長さのメモリだけを確保するようにしています。 その結果、一時的に確保するメモリの量が格段に少なくなります。 行数を指定できるため、最後から何行分の結果が必要と言う際に利用できます。 実行結果
・ファイルの内容を一行ずつ読み取る
・その結果を配列として保存
・配列の結果を逆から取得する
という手順となります。 その際、確保するメモリの量が行数分+最終的な結果の分となるためメモリの確保に困りますが、以下の例題では一時的に確保するメモリの代わりにファイルポインタの位置、行の長さのメモリだけを確保するようにしています。 その結果、一時的に確保するメモリの量が格段に少なくなります。 行数を指定できるため、最後から何行分の結果が必要と言う際に利用できます。 実行結果
登録:
投稿 (Atom)
