色々調べてみた結果、符号付きでなく、かつ整数の場合なら以下のソースコードで実装できました。
できていません。コンパイルできるソースに書き直してください。
istringstream を使えばできます。
C++
1#include <iostream> // cout
2#include <string> // string
3#include <vector> // vector
4#include <sstream> // istringstream
5using namespace std;
6
7int main()
8{
9 // string s="44iiyo-2";
10 string s = "1233,2912 -9 0 -8.2";
11 vector<int> vec;
12
13 istringstream iss(s);
14 for (;;) {
15 int v; iss >> v;
16 if (iss)
17 vec.push_back(v);
18 else {
19 if (iss.eof()) break;
20 iss.clear();
21 iss.ignore();
22 }
23 }
24 for (int i = 0; i < vec.size(); i++)
25 cout << vec[i] << endl;
26}
このコードが動いたからといって、「解決しました」だけで済まさず、
理解したかどうかをコメントしてください。
追記
int の代わりに double として読み込むなら、
C++
1#include <iostream> // cout
2#include <string> // string
3#include <vector> // vector
4#include <sstream> // istringstream
5#include <iomanip> // setprecision
6using namespace std;
7
8int main()
9{
10 string s = "1233,2912 -9 0 -8.2";
11 vector<double> vec;
12
13 istringstream iss(s);
14 for (double v; ; )
15 if (iss >> v) vec.push_back(v);
16 else if (iss.eof()) break;
17 else iss.clear(), iss.ignore();
18
19 cout << fixed << setprecision(1);
20 for (auto v : vec) cout << v << endl;
21}
追記2
コンパイルできるソースに修正されたようですが、まだ問題があります。
s は "44iiyo2" ですから、s.length() は 7 です。
char *a = new chars.length(); で 7バイトの領域が確保され、ゼロで初期化され、a はその領域を指します。
strncpy(a, s.c_str(), s.length()); で a の指す領域に 7バイトコピーされますが、文字列の終端を示す '\0' はコピーされません。
従って while (*a) でループが終了するかどうかは不定です。
s.c_str() が s の中の "44iiyo2" という '\0' で終端する文字列を返すので、
const char *a = s.c_str(); で十分です。
符号付で読み込みたいなら、isdigit だけでなく '-' や '+' もチェックすべきでしょう。
C++
1#include <vector> // vector
2#include <string> // string
3#include <iostream> // cout, endl
4#include <cstdlib> // strtol
5using namespace std;
6
7int main()
8{
9 string s = "1233,2912 -9 0 -8.2";
10 vector<int> vec;
11 const char *a = s.c_str();
12 while (*a) {
13 if (isdigit(*a) || *a == '-' || *a == '+') {
14 char *b;
15 int v = (int) strtol(a, &b, 10);
16 if (b == a) // 符号の後に数字が来ない場合のエラーをチェック
17 a++;
18 else {
19 vec.push_back(v);
20 a = b;
21 }
22 } else
23 a++;
24 }
25 for (int i = 0; i < vec.size(); i++) cout << vec[i] << endl;
26}
int の代わりに double で読み込みたい場合は、
vevtor<double> vec; にして、double v = strtod(a, &b); とすればよいでしょう。
コメントにある質問への回答
②if(iss)によってissのfailbitが立っていないか確認。
failbit だけでなく、eofbit も badbit も立っていなくて
正常に数値を読み込んだことを確認しています。
①iss>>v という操作を行った後、issはどう変化しているのか?(読み取り位置が変化しているという認識でいいのか?)
正常に数値を読み込んだときは、読み取り位置が変化しますが、
数値を読み込めなかったときは、読み取り位置は変わらず、
failbit または eofbit が立ちます。
②issのfailbitが立った場合にbreakから抜け出してもこのプログラムは正常に動く気がするが、issに対しclearとignoreを施しているのはなぜか?(このプログラムを書き加えてissを再利用する場合に備えているため?)
eofbit が立った場合は、break で forループを抜けますが、
failbit が立った場合、ループは継続します。
clear で failbit をリセットしないと、次の iss >> v が実行できません。
ignore で読み取り位置を一つ進めないと、次の iss >> v で同じ結果になります。
③eof()は読み取り位置が終端まで来たかどうかを判定しているという認識でよいか。
そういう認識でよいでしょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/01/05 05:53 編集
2020/01/05 05:51
2020/01/06 07:36