前提
C++を学校で学んでいます。以下のコードが理解できず行き詰っています。
該当のソースコード
#include <iostream> #include <fstream> #include <sstream> using namespace std; typedef struct student{ string name; string id; double gpa; struct student* next; }Student; int main(){ ifstream ifs("data3.csv"); string line; stringstream stream; Student *top = NULL; Student *sp; while(getline(ifs, line)){ sp = new Student; sp->next = top; top = sp; stream.clear(); stream << line; getline(stream,sp->name,','); getline(stream,sp->id,','); stream >> sp->gpa; } sp = top; while(sp != NULL){ cout << sp->name << "," << sp->id <<"," << sp->gpa << endl; sp = sp->next; } ifs.close(); }
data3.csv
まるた まるお,00k0000,3.25
かくた かくこ,00k0001,2.84
てんだ てんこ,00k0002,3.01
一個目のwhile文が何をどうしているのか理解ができません。
特にtop = sp; はなぜいるのでしょうか
変数名がtopなんだったら、リスト構造の先頭を指すべきでしょうね。
1つ前の要素を指す。と、更新していっているので、
データ入れ終わった時に先頭が行方不明になります。
単方向リストなので先頭まで戻れない。
top:先頭の要素へのポインタ
sp:追加する要素を保持するインスタンス
となりますが…まぁよろしくない例なんでしょうな。
sp->next = new Student;
sp = sp->next;
が妥当じゃないですかねぇ。
spを変更する前に、topがnullだったら保存しておく必要はありますが。
素直にstd::list使うべきじゃないですかね。
回答を書きましたが,新規要素はリストの末尾ではなく先頭に追加していく形だと思いますよ.
topは常に先頭を指しています.
spの方は繋ぎ変え作業中にのみ必要なだけの存在ですね.
例えば,仮に Student に next メンバを初期化するための引数を持つコンストラクタがあるとしたら
top = new Student(top);
みたいな話で,spは要らない.
変数名 top がイマイチで混乱させてますね。
トップ ではなく sp が StudentPoint なのの類推からすると ToPoint のつもりだったのかな。。。
sp->next = top だと、トップではなく テイル になるように思えるのだが。
sp->prev = top とすれば トップはトップになるが。そこで top ではなく prevp と命名しておけば、順繰り感が入るかなぁ。
top だと トップ の感強く、それだと 順繰りではなく 端の一点という感。
while(getline(ifs, line)) は
ifs から 1行 lineへ読み込んで、それが成功している間繰り返す
という意味です。
これってキホンのキ ですよ
? リストの先頭要素を指す用のものを "top" と名付けていることにそんな違和感あるかな?
("sp" の方は「すごいポインタ」あたりを推す)
順序的にスタック的なことをしようとしているから "top" とかいう名前なのかもしれぬ.
そうすると "sp" は「スタックポインタ」あたりから来ているのだろうか?
でもそんな話なら "top" の方を "sp" と命名すべきような気がしないでもないが…まぁどうでもいい.
先頭のものをtopとするのは全く違和感ないですが、
top = sp; の時点で先頭じゃなくなってますよね、
それに
sp->next = top; ということは、 sp の次が top ということでこれは sp が先頭になってない?
CSVに 生徒1、生徒2、生徒3 とならんでたとき、先頭は生徒1 だと言うのが自然ですが(よね?)
このプログラムの処理の結果、
生徒3-> next ⇒ 生徒2->next ⇒ 生徒1
というListになります。このデータだと 生徒3が先頭では?
これが完成した時点では top は 生徒2で、どちらから見ても先頭とは言えない
StudrntPointa だとおもってました。