teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

3

追記3

2021/06/11 12:07

投稿

kazuma-s
kazuma-s

スコア8222

answer CHANGED
@@ -75,4 +75,45 @@
75
75
  for (auto e : v) cout << e << endl;
76
76
  を入れてみてください。
77
77
 
78
- とにかく、どんなふうにデバッグしているかを教えてください。
78
+ とにかく、どんなふうにデバッグしているかを教えてください。
79
+
80
+ **追記3**
81
+ ```C++
82
+ class Table {
83
+ friend Record;
84
+ std::vector<Record> v;
85
+ public:
86
+ void add(Record r) { v.push_back(r); }
87
+ ...
88
+ };
89
+
90
+ #include <sstream> // istringstream
91
+
92
+ std::vector<std::string> split(std::string s)
93
+ {
94
+ std::vector<std::string> v;
95
+ std::istringstream iss(s);
96
+ std::string t;
97
+ while (iss >> t) v.push_back(t);
98
+ return v;
99
+ }
100
+
101
+ void import(std::ifstream & fin, Table & table)
102
+ {
103
+ while (true) {
104
+ Record record;
105
+ std::string s;
106
+ if (!getline(fin, s)) break;
107
+ record.set_r(s);
108
+ if (!getline(fin, s)) break;
109
+ record.set_n(s);
110
+ if (!getline(fin, s)) break;
111
+ record.set_s(split(s));
112
+ if (!getline(fin, s)) break;
113
+ record.set_a(split(s));
114
+ table.add(record);
115
+ getline(fin, s);
116
+ }
117
+ }
118
+ ```
119
+ どんなふうにデバッグしているかを教えてください。

2

デバッガ使ってますか?

2021/06/11 12:07

投稿

kazuma-s
kazuma-s

スコア8222

answer CHANGED
@@ -39,4 +39,40 @@
39
39
  getline(fin, score);
40
40
  getline(fin, aite);
41
41
  getline(fin, blank);
42
- で思い通りに読み込めます。
42
+ で思い通りに読み込めます。
43
+
44
+ **追記2**
45
+ どんなふうにデバッグしているか教えてください。
46
+
47
+ どこで Segmentation falut しているか、
48
+ デバッガを使っているのなら、すぐに分かります。
49
+
50
+ デバッガを使えないなら、次のようにすれば、範囲を絞れます。
51
+ ```C++
52
+ import(fin,table);
53
+ std::cout << "import done\n";
54
+ table.print();
55
+ std::cout << "print done\n";
56
+ table.sort();
57
+ std::cout << "sort done\n";
58
+ table.result(fout);
59
+ return 0;
60
+ ```
61
+ 実行結果
62
+ ```text
63
+ import done
64
+ print done
65
+ Segmentation fault (core dumped)
66
+ ```
67
+ table.sort() の中で Segmentation fault していますね。
68
+ table.print() は問題ない。いや、問題大ありです。
69
+ 読み込んだものが何も表示されないなんて変です。
70
+ では、print() が間違っているのか?
71
+ そうではなくて、import() で table に何も読み込んでいないのかもしれません。
72
+ split() が正しく動いるかどうか確かめてください。
73
+ return v; の前に、
74
+ cout << "v.size() = " << v.size() << "\n";
75
+ for (auto e : v) cout << e << endl;
76
+ を入れてみてください。
77
+
78
+ とにかく、どんなふうにデバッグしているかを教えてください。

1

fin >> と getline の説明を追加

2021/06/10 14:21

投稿

kazuma-s
kazuma-s

スコア8222

answer CHANGED
@@ -9,4 +9,34 @@
9
9
  for文は回りません。v に r は追加できません。
10
10
 
11
11
  とにかくどこまで思い通りに行っているのか、main からステップ実行して
12
- すべての変数の値の変化を見てください。
12
+ すべての変数の値の変化を見てください。
13
+
14
+ **追記**
15
+ `ifstream fin("file.txt"); int i; double d; string s; fin >> i >> d >> s;`
16
+ とあった時、ファイルの内容が「123 4.5 abc」であれば、
17
+ i = 123、d = 4.5、s = "abc" と読み込めることは知っていますよね。
18
+
19
+ ifstream は istream から派生していて、istream の operator>> はデフォルトで
20
+ 空白文字(スペース、タブ、改行など)を読み飛ばすモードになっています。
21
+ だから「123タブ4.5改行abc」であっても同じように読み込めます。
22
+
23
+ 入力が「Yokozuna改行Hakuhou改行タブShiroboshiスペースShiroboshi改行Daieishou」だと、
24
+
25
+ `fin >> rank; fin >> name; fin >> score; fin >> aite;` で
26
+ rank = "Yokozuna"、name = "Hakuhou"、score = "Shiroboshi"、aite = "Shiroboshi" となります。
27
+ score に「タブShiroboshiスペースShiroboshi改行」の 1行を読み込ませたかったら
28
+ getline を使います。
29
+
30
+ ところが、fin >> name; のとき "Hakuhou" の次の改行がまだ入力ストリームに
31
+ 残ったままなので、getline(fin, score); ではその「改行」だけが読み込まれ、
32
+ 「改行」は削除されるので、score = "" となります。
33
+ getline(fin, blank); getline(fin, score); のようにすると、
34
+ score には 1行の文字列が入力できます。
35
+
36
+ ファイルの最初の 2行の「Yokozuna改行Hakuhou改行」にスペースがないのであれば
37
+ getline(fin, rank);
38
+ getline(fin, name);
39
+ getline(fin, score);
40
+ getline(fin, aite);
41
+ getline(fin, blank);
42
+ で思い通りに読み込めます。