タグ別アーカイブ: Programming

C++に関する記録

気付けば冬ですが、けいなです。

今回はC++に関して試行錯誤したことについて書きます。

お気楽参加のTopCoder SRMやAtCoder、絶賛放置中のAOJではJavaを使いです。
C++は随分前に手を出そうとして環境構築との戦いに負けて放置していました。
(高校ではポインタと構造体の無いC言語と簡単なBorland C++だった筈なのに)
とある事情によりC++に軽く触れておかなければならなくなったので、
環境構築をしたのですが前回と同様に痛い目にあったので少しまとめておきます。

TopCoder SRMでEclipse上のEclipseCoderに頼りきりな人です。
当然、C++もまずはEclipseで、と考えました。

#include <iostream>
using namespace std;

int main(){
	cout << "Hello World!\n";
	return 0;
}

なんの変哲もないHello Worldを打ち込んでプロジェクトをコンパイルして実行…したところターミナルになにも出力されない。

調べるとEclipseとMinGWの組み合わせで、64bitの時に生じるバグのよう。
リンカのオプションに-staticを渡してやると直ることが分かったのでプロジェクトのプロパティから適当に挿入して解決。
前に嵌ったのはこれだったので前回は調査不足だったということですね、残念。

次に、適当にテストケースを放り込むものをEclipseCoderのC++で生成されるものを流用して使うことに。
で、何も考えずに次のようなコードを書いてコンパイルできずに死亡。

	vector<int> expected_ = { 0, 13};

C++11で導入された記法らしいということに辿り着くまでにすこしかかったもののたどり着いてからは早く。
コンパイラのオプションに-std=c++11を渡してやるとコンパイル通るので適当に。

が、この環境を構築したWindows 8はバッテリーの食い方が異様なので電源を使用していない時はほとんど使っていません。
SRMの環境としてなぜかBoot Campで動いているWindows 8のEclipseを使用しているため普段は使用されることなく。
結局、環境作った筈なのに全く進まない。(正直Appleには頑張って欲しいところ、トラックパッドのドライバとか特に!)

そこで、Macで書けるようにしようということでclangとバトル。
これがまたあまりうまく行かなかった。普段C++を使わない人が適当に頑張ろうとするのが悪いのだろうと思いつつ延々。
clangに対してWindows 8+MinGW+Eclipseで成功した-std=c++11辺りを放り込んで色々やっていたもののあまりうまく行かず。

clang++ -std=c++11 -std=libc++ probtest.cpp

結論はあっけなく。c++として認識させろということでした、はい。

と、Macで書けるようになった。この程度だとvimとコンソールで書けるしWindowsのcygwinでできるのでは…ということで色々。

clang++と試行錯誤しつつ延々酷い目にあって、C_INCLUDE_PATHやCPLUS_INCLUDE_PATH、LIBRARY_PATHを弄っていて。
Eclipse側が読み込んでいるPleiadesお抱えのMinGW配下のファイルを読み込ませても上手く行かなかった。
そこで方針転換。cygwinが抱えているヘッダファイル達を読み込む方向に転換するもなにかがおかしい。
clangやgccが抱えていたヘッダファイル等をEclipseの読み先と似たように持ってきているのに全く通らず。

エラー吐いている部分を適当にググるとStackOverFlowがヒットして、調べるとcygwinのgccがこの例と同じく4.5.3。
cygwinのインストーラーを持ってきて4.5.3を使っている部分をすべからく4.7.2にアップデートしたところコンパイル成功。

clang++ -std=c++ probtest.cpp

教訓:環境とデフォルト設定を疑え

と、これでコンソールで書けるようになったのでDropboxか何かで同期させておけばいつでもできる。
引数の微妙な差分は.zshrcで環境ごとにalias通して作業すれば十分。

しかし…TopCoderはC++11じゃないしこの環境だと参加するには微妙なところだな…。

python-twitterで遊んだ。

ちょっとした興味で作った駄作について。

ちょっとコミケに遊びに行こうと思い、そのモバイル環境でTLが取得できないことを予測。使用しているモバイル環境がdocomo系MVNOのものなのでdocomoの比率の高さに加えて本家に潰される可能性がある。

で、VPSでTLを取得してメールで送りつければ良いのではという考えで作ったもの。

10秒に1回、自分のタイムラインを直近100件読み込んで、古いものから順にidを調べ、既に書き出しているものより大きいものをファイルに書き出すというもの。

import sys
import codecs
import time
import twitter

api = twitter.Api(consumer_key='適切な文字列', consumer_secret='適切な文字列', access_token_key='適切な文字列', access_token_secret='適切な文字列', cache=None)

tmp = 0

timeline = api.GetFriendsTimeline('@以下の文字列', 100, 0, 0, True, True)
timeline.reverse();
f = open("1.log","w")
f = codecs.getwriter('utf-8')(f)
for tweet in timeline:
	f.write('\n%s(%s)\n%s\n.' % (tweet.user.name, tweet.user.screen_name, tweet.text))
	if tmp < tweet.id:
		tmp = tweet.id
f.close();

while 1:
	time.sleep(120)
	timeline = api.GetFriendsTimeline('@以下の文字列', 100, 0, 0, True, True)
	timeline.reverse();
	f = open("1.log","a")
	f = codecs.getwriter('utf-8')(f)
	for tweet in timeline:
		if tmp < tweet.id:
			tmp = tweet.id
			f.write('\n%s(%s)\n%s\n.' % (tweet.user.name, tweet.user.screen_name, tweet.text))
	f.close();

また、取得したファイルを送りつけるようなシェルスクリプトを準備して回した。

#!/bin/zsh
while true
do
	export aaaa=`date +"%Y.%m.%d-%T"`
	mail -s $aaaa 送信先のメールアドレス < ./1.log
	rm -f ./1.log
	sleep 5m
done

出力されたファイルをリダイレクトでmailコマンドに放り込み、送信した時間を件名に埋め込んだだけの何か。送った後5分間休むので5分間隔で送りつけてくれる。cronを初めて使ったら添付ファイルになったので急遽作った。何が悪かったのかは今後。

この2つを借りているVPSで起こしたscreenの下で実行。5分間隔というのが少し短くて時々苛立ったが取得漏れ以外は追いかけることが可能だったのである程度重宝した。

メールでの通知は止めたがpythonのコードの方はその後も無駄に動かし続けている。10秒間隔が悪いのかは不明だが1日とか8時間とかで倒れてしまう現象が発覚。python-twitter側でエラーが起きて倒れるのでライブラリ自体が不穏な可能性もあるがとりあえず120秒間隔で取得するようにしたところ3日動き続けている。

pyhonなにそれという状態からライブラリを探しTwitterでアプリの登録をしてTLを吐き出すコードを書き、mailコマンドを適当に叩くところまでで4時間というので適当だがこういう駄作でもなにか作るとある程度調べるから悪くない。