回答編集履歴

4

コメントの質問への回答を追加

2020/01/05 17:23

投稿

kazuma-s
kazuma-s

スコア8224

test CHANGED
@@ -207,3 +207,49 @@
207
207
  int の代わりに double で読み込みたい場合は、
208
208
 
209
209
  vevtor<double> vec; にして、double v = strtod(a, &b); とすればよいでしょう。
210
+
211
+
212
+
213
+ **コメントにある質問への回答**
214
+
215
+ > ②if(iss)によってissのfailbitが立っていないか確認。
216
+
217
+
218
+
219
+ failbit だけでなく、eofbit も badbit も立っていなくて
220
+
221
+ 正常に数値を読み込んだことを確認しています。
222
+
223
+
224
+
225
+ > ①iss>>v という操作を行った後、issはどう変化しているのか?(読み取り位置が変化しているという認識でいいのか?)
226
+
227
+
228
+
229
+ 正常に数値を読み込んだときは、読み取り位置が変化しますが、
230
+
231
+ 数値を読み込めなかったときは、読み取り位置は変わらず、
232
+
233
+ failbit または eofbit が立ちます。
234
+
235
+
236
+
237
+ > ②issのfailbitが立った場合にbreakから抜け出してもこのプログラムは正常に動く気がするが、issに対しclearとignoreを施しているのはなぜか?(このプログラムを書き加えてissを再利用する場合に備えているため?)
238
+
239
+
240
+
241
+ eofbit が立った場合は、break で forループを抜けますが、
242
+
243
+ failbit が立った場合、ループは継続します。
244
+
245
+ clear で failbit をリセットしないと、次の iss >> v が実行できません。
246
+
247
+ ignore で読み取り位置を一つ進めないと、次の iss >> v で同じ結果になります。
248
+
249
+
250
+
251
+ > ③eof()は読み取り位置が終端まで来たかどうかを判定しているという認識でよいか。
252
+
253
+
254
+
255
+ そういう認識でよいでしょう。

3

修正されたソースの問題点を指摘

2020/01/05 17:22

投稿

kazuma-s
kazuma-s

スコア8224

test CHANGED
@@ -121,3 +121,89 @@
121
121
  }
122
122
 
123
123
  ```
124
+
125
+  
126
+
127
+ **追記2**
128
+
129
+ コンパイルできるソースに修正されたようですが、まだ問題があります。
130
+
131
+
132
+
133
+ s は "44iiyo2" ですから、s.length() は 7 です。
134
+
135
+ char *a = new char[s.length()](); で 7バイトの領域が確保され、ゼロで初期化され、a はその領域を指します。
136
+
137
+ strncpy(a, s.c_str(), s.length()); で a の指す領域に 7バイトコピーされますが、文字列の終端を示す '\0' はコピーされません。
138
+
139
+ 従って while (*a) でループが終了するかどうかは不定です。
140
+
141
+
142
+
143
+ s.c_str() が s の中の "44iiyo2" という '\0' で終端する文字列を返すので、
144
+
145
+ const char *a = s.c_str(); で十分です。
146
+
147
+
148
+
149
+ 符号付で読み込みたいなら、isdigit だけでなく '-' や '+' もチェックすべきでしょう。
150
+
151
+ ```C++
152
+
153
+ #include <vector> // vector
154
+
155
+ #include <string> // string
156
+
157
+ #include <iostream> // cout, endl
158
+
159
+ #include <cstdlib> // strtol
160
+
161
+ using namespace std;
162
+
163
+
164
+
165
+ int main()
166
+
167
+ {
168
+
169
+ string s = "1233,2912 -9 0 -8.2";
170
+
171
+ vector<int> vec;
172
+
173
+ const char *a = s.c_str();
174
+
175
+ while (*a) {
176
+
177
+ if (isdigit(*a) || *a == '-' || *a == '+') {
178
+
179
+ char *b;
180
+
181
+ int v = (int) strtol(a, &b, 10);
182
+
183
+ if (b == a) // 符号の後に数字が来ない場合のエラーをチェック
184
+
185
+ a++;
186
+
187
+ else {
188
+
189
+ vec.push_back(v);
190
+
191
+ a = b;
192
+
193
+ }
194
+
195
+ } else
196
+
197
+ a++;
198
+
199
+ }
200
+
201
+ for (int i = 0; i < vec.size(); i++) cout << vec[i] << endl;
202
+
203
+ }
204
+
205
+ ```
206
+
207
+ int の代わりに double で読み込みたい場合は、
208
+
209
+ vevtor<double> vec; にして、double v = strtod(a, &b); とすればよいでしょう。

2

double を読み込むコードを追加

2020/01/04 23:39

投稿

kazuma-s
kazuma-s

スコア8224

test CHANGED
@@ -69,3 +69,55 @@
69
69
  このコードが動いたからといって、「解決しました」だけで済まさず、
70
70
 
71
71
  理解したかどうかをコメントしてください。
72
+
73
+
74
+
75
+ **追記**
76
+
77
+ int の代わりに double として読み込むなら、
78
+
79
+ ```C++
80
+
81
+ #include <iostream> // cout
82
+
83
+ #include <string> // string
84
+
85
+ #include <vector> // vector
86
+
87
+ #include <sstream> // istringstream
88
+
89
+ #include <iomanip> // setprecision
90
+
91
+ using namespace std;
92
+
93
+
94
+
95
+ int main()
96
+
97
+ {
98
+
99
+ string s = "1233,2912 -9 0 -8.2";
100
+
101
+ vector<double> vec;
102
+
103
+
104
+
105
+ istringstream iss(s);
106
+
107
+ for (double v; ; )
108
+
109
+ if (iss >> v) vec.push_back(v);
110
+
111
+ else if (iss.eof()) break;
112
+
113
+ else iss.clear(), iss.ignore();
114
+
115
+
116
+
117
+ cout << fixed << setprecision(1);
118
+
119
+ for (auto v : vec) cout << v << endl;
120
+
121
+ }
122
+
123
+ ```

1

ignore() に変更

2020/01/04 05:34

投稿

kazuma-s
kazuma-s

スコア8224

test CHANGED
@@ -52,7 +52,7 @@
52
52
 
53
53
  iss.clear();
54
54
 
55
- char c; iss >> c;
55
+ iss.ignore();
56
56
 
57
57
  }
58
58