2015年2月20日金曜日

while()と.eof()でのファイル読み出しの最終行重複の謎が解けた

テキストファイルをwhileループで読み出すと最終行が重複する謎について解けたので報告する。




ようするに、whileループは、do-while的に使え、ということです。


つまり、ファイルの読み込みにおいてはいきなりwhile()を呼び出してはいけません。
先に一度ファイル読み込みを行っておく必要がある、ということでした。


こうすると、期待したとおりに動作します。




具体的には、
(数字がかかれたテキストファイルを読み込む場合)
"somefile.txt"の中身。
0.0
1.0
2.0
3.0
--------------------------------------------------------------------------------------------
#include<fstream>
#include<iostream>


int main(){
  ifstream fin("somefile.txt");
  //エラーチェックなどは省略。


  double buf;


  fin >> buf;            //この一行をここで入れるのがポイントです!!
    while(!fin.eof()){
      fin >> buf;
      cout << buf;
    }


  return 0;
}
--------------------------------------------------------------------------------------------
結果はテキストファイルと同じです。(あたりまえの動作がやっと実現)。


こうやっておけばもう怖いものはない!!


なお、eof()の括弧を忘れないように!ないとコンパイル時に難しいこと言われます。
よかったよかった。

2014年7月20日日曜日

Visual Studio 2013の便利ショートカットキー

今回は

● 行の移動 (Alt + ↑, Alt + ↓)

行ごと移動する(カットアンドペーストと同じ機能)ことが、なんと
Alt+↑キーまたは↓キーで簡単にできてしまうようです。すごい。

http://blogs.msdn.com/b/chack/archive/2013/08/20/visual-studio-2013-new-editor-features.aspx


これらも便利そうです。

 Ctrl + カーソルを 1 単語右へ移動。
 Ctrl + カーソルを前の単語の先頭に移動。
 
 Ctrl + ]カーソルをドキュメント内の次の中かっこ ({}) に移動。

2014年6月12日木曜日

ファイルの読み出しにおけるwhile(!myifstream.efo())はバグの元

C++の最大の利点はSTLだという。最近これを実感したので、たまらず記事にしたくなった。これがこのブログのきっかけだ。

listは重複する値の削除のメソッド .unique()とソート処理の.sort()がまず便利だ。もう配列は使わないでいいかも、と思ってしまう。

mapと組み合わせることで、list<pair<int,double> > mylist;
実装は、mylist.pushback(make_pair(11,2.2));
読み出しは、list<pair<int,double> >::iterator  mylist_p; を宣言しておいて、
mylist_p->firstとすると11が、mylist_p->firstとすると2.2が読み出されるのは知っておいて損はない。
こうすることで2つの値をもつリストを作れるので、簡単な表計算っぽいことが簡単にできる。

はい、次です。
ファイルの読み込みを行いつつ計算などをする場合、はまるので注意。
つまりファイル全体を読むのに、末尾まで読むという定番の処理while(!myifstream.efo()) をやりつつ読んだ結果を出力すると、なんと最終行が重複するのだ

たとえば、読み込みファイルの中身が
1
2
3
4
これを上のようにEOFまで読み出すようにすると、こうなる:
1
2
3
4
4
一行多いのです。平均値を求める場合などはこれに気づかないで単純に足していったりするとおかしくなります。というか私はこの処理をやっていてどうにもおかしく、構文上理解不可能なバグだったので悩んだ末、いろいろ調べてようやくこの問題に気づきました。

これはC++の仕様どおりだそうだが、これは欠陥ではないのか?直すべきだと思われる。

今日は以上。