2015年6月21日日曜日

g++における、getline()の戻り値について

cのときからテキストファイルを読み込むときによく使っていたのがgetline()でした。

ssize_t getline(char** , size_t , FILE* )

1行ずつ読込、戻り値に読み込んだ文字数が返ってくるため、ファイルの最後までいくと読めないので、文字数0が返ってきました。それを使って、最後まで読んだかをチェックするのが普通でした。

while ( getline(line, 256, fp) !=0 )

こんな感じです。c++になるとifstreamで同じ関数があり、確か最初(20年くらい前)は同じ仕様だったと思います。ずっとそう思っていました…

Macのxcodeで既存のlinuxで作成したプログラムをコンパイルしようとすると、どうしてもこのgetline()でエラーがでて、ずっと悩んでいましたが今日やっと理由がわかりました。c++でのgetline()の戻り値はifstream自身でした。
つまり、読込に成功したら"true"、最後までいき失敗したら"false"を返すようになってました。
でもこれまでlinuxの方では、0とかNULLで比較していても何もいってこなかったんで気付きませんでしたが、本当は以下のようにチェックすべきでした。

while ( fp.getline(line, 256))

linuxの方は昔のcの実装がboolがなくて、unsigned intでやれ、という指定だったためそれとの互換性を考えていたようです。しかしmacは厳密にチェックするようになったため、エラーにしているようです。さて、既存の遺産をどうするか注意しないと。


2015年6月13日土曜日

既存のgit管理されたCプログラムをeclipseで開発

久しぶりにちょっとした備忘録です。

1.概要
2.eclipseで操作する前の状態
3.eclipseで操作する状態
4.やった方が感じがいいこと

こんな感じで進めていきたいと思います。

1.概要
他のPC、或いは既にプロジェクトが少し進んでいてそれがgit管理されています。そこに参加した、或いは最初はソースコードを書いていただけで、実際のコンパイルをこれから始めるという状況です。
Linuxを想定しますが、eclipse-CDTだとC/C++プロジェクトを作成でき、しかも今はGit管理パッケージが最初から入っています。(数年前はGit管理パッケージが最初は入っていなくて、いちいちEGitを後から入れたりして大変でした)

話を簡単にするために以下の状況を想定します。

・ソースはgithub等のリポジトリにあるわけではなく、何故かローカルでPCに入れてあります。(分散リポジトリなんで、簡単に実現できます)
・~/ProgWork/work以下にgit管理されたソースが入っています。
・そこにはmain.cだけが入っています。
・当然、~/ProgWork/workには .git ディレクトリがあります。

つまり、このgit管理されたものをeclipseで開発を(gitを使いながら)継続したいというわけです。

2.eclipseで操作する前の状態
とりあえずデフォルトの状態として、eclipseの作業ディレクトリは、$HOME/workspaceとしておきます。最初はもちろん何もプロジェクトがなく、空っぽとします。(注:でも最新のeclipseだと、workspace/RemoteSystemTemFilesなんてディレクトリができていました。何でしょこれ?)

3.eclipseで操作する状態
やることは以下の通りです。

(1)eclipseでFileメニューから"Import"を選択する。
(2)選択Dialogが表示されます。その中に、"Git"があります。"Projects from Git"を選択してNextします。
(3)次のDialogで"Existing local repository"というのがでてきますので、これを選択します。(注:ちなみに通常は外部のgithub等からプロジェクトをとってきますから、もう一つの"Clone URI"を選択します。こっちのやり方は以前にも書きましたのでここでは省略します。)
(4)ここで、~/ProgWork/work/.gitを選択します。
(5)後はproject wizardに進みますので、そのまま作業を進めればeclipseで開発が続けれます。
(6)ただこれではプロジェクトを作っただけで、まだ肝心のソースファイルがプロジェクトに入っていません。Fileメニューで作ったプロジェクトにソースファイルを追加してやります。
(7)ただこれだけではまだ、このプロジェクトはGit管理できません。eclipseのTeamメニューでもいつものGit関係のコマンドがでてきません。Teamメニューから"Share project"をしてやる必要があります。

ところでこの状態でディレクトリの状態はどうなっているんでしょう?ここからは実は2通りあります。今回ブログを書くにあたって実験してたら、2通りの状態になってしまいました。どちらが正しい状態かはわかりませんが、どちらも動くようなのでたまたまなのでしょう。

"sample"というc/c++のプロジェクトを作りましたが、~/ProgWork/work/sampleというディレクトリが作成されました。ビルドしたバイナリはここにできます。
問題は、eclipseが管理する、".project"なんですが、これが~/ProgWork/work/sampleにできる場合と、eclipseのデフォルトの、~/workspace/sampleにできる場合の2通りにわかれました。
どちらの場合でも、結局元のソースは~/ProgWork/work/以下にあり、eclipseからは普通に操作できますし、gitでcommitもできます。
(実は、自分はここでworkspace/sample以下にコピーが作成されてしまい、eclipse独自のgit管理に入ってしまうかと予想していましたが、そんなことはありませんでした^^;)

4.やった方が感じがいいこと
さて、残る問題はeclipseによって勝手に作成される、~/ProgWork/work/sampleというディレクトリです。これがgit管理下には入っていませんから、よくgitから文句を言われます。
こんなときは、~/ProgWork/work/.gitignoreファイルを作り、そこに"sample/"と文字列を追加しておけば、gitはそれは自分の管轄外と思ってくれて無視してくれます。
ただ、さらにいうと今度は".gitignore"も管理に入れろとgitは文句をいってきます。これを.gitignoreに含めるかは、宗教の問題になってきます。会社などで同じ開発環境で作業しているなら、.gitiginore自体も共有すべきだというのが、通常の考え方なんだそうです。ただまあこれは好みの問題で、自分の様に個人で遊んでいる場合には.gitiginoreに自身も含めてしまっています。
(だって、"git status"で毎回なんか文句言われると気になるから)