2019年05月08日(水) [長年日記]
■ [c++] reverse_iteratorが指す要素の削除
reverse_iteratorが指す要素の削除方法をメモしておく。Effective STLの第28項「reverse_iteratorの基底iteratorの使い方を理解しよう」に説明がある。
- コンテナのerase()メソッドはreverse_iteratorを受け付けないので、reverse_iteratorのbase()メソッドによりiteratorオブジェクトを取得する必要がある。
- base()が返すイテレータが指す要素はreverse_iteratorが指す要素からend()方向に1つずれているので、erase()に渡す際にはイテレータの位置を調整する必要がある。調整には (++rit).base() のようにreverse_iteratorを1つ進めてからbase()を呼ぶべしとEffective STLにある。
rend() rit rbegin() +-------+-------+-----+-------+-------+-----+-------+-------+ | a | b | ... | h | i | ... | y | z | +-------+-------+-----+-------+-------+-----+-------+-------+ begin() rit.base() end()
#include <algorithm> #include <iostream> #include <numeric> #include <vector> int main() { std::vector<int> v(10); std::iota(v.begin(), v.end(), 1); auto rit = std::find_if( v.rbegin(), v.rend(), [](int i) { return i % 3 == 0; }); if (rit != v.rend()) { // reverse_iterator::base()が返すイテレータは指す要素が異なるので調整が必要 // see Effective STL 第28項 v.erase((++rit).base()); } for (const auto& e : v) { std::cout << e << " "; } std::cout << std::endl; }
1 2 3 4 5 6 7 8 10
2019年05月21日(火) [長年日記]
2019年05月30日(木) [長年日記]
■ [windows] WSLでクリップボードへコピー
WSLを使っていてテキストをクリップボードへコピーしたいことがある。この用途にWindowsのclipコマンド(clip.exe)が使えることを知ったのでメモ。
clipコマンドはWSLだけでなくコマンドプロンプトなどからも使える。便利。
% ls | clip.exe
% type clip.exe clip.exe is /mnt/c/Windows/System32/clip.exe % clip.exe /\? CLIP 説明: コマンド ライン ツールの出力を Windows クリップボードにリダイレクトします。 その出力されたテキストをほかのプログラムに貼り付けることができます。 パラメーター一覧: /? このヘルプを表示します。 例: DIR | CLIP 現在のディレクトリ一覧のコピーを Windows クリップボード に貼り付けます。 CLIP < README.TXT readme.txt ファイルのテキストのコピーを Windows クリップボードに貼り付けます
2019年05月31日(金) [長年日記]
■ [ruby] Rubyで簡単なファイル編集
Rubyで簡単なファイル編集を行うならワンライナーで済ますのがよい。ワンライナーを書くにはコマンドラインオプションの
- -e script
- 実行するスクリプトを指定する。
- -i[extension]
- 引数で指定されたファイル群の内容を、標準出力へ書き込まれた内容で置き換える。extensionを指定すると変更前のファイルを残せる。
- -l
- -nオプションの読込結果(変数$_)が改行を含まなくなる。
- -n
- 引数でしたファイル群の各行(行の内容は変数$_に設定される)に対して-eオプションで指定されたスクリプトを実行する。
あたりを使用する。
% ruby -nli -e 'print $_.gsub(/\+(\w+)\+/, "`\\1`").gsub(/_(\w+)_/, "*\\1*")' dir/**/*
ワンライナーにしないなら、ARGFを使うと同じ事ができる。
ARGF.inplace_mode = "" ARGF.each_line do |line| print line.gsub(/\+(\w+)\+/, "`\\1`").gsub(/_(\w+)_/, "*\\1*") end
ただ、inplace_modeを使うと標準出力への出力がファイルに出力されてしまうので注意が必要。
inplace_modeって取り消すことはできないのかな?