「102:330:3133:76531:451:000:12:44412
」などの文字列を「:
」文字で分割し、すべての数値をint配列に入れるにはどうすればよいですか(数値シーケンスは常に8の長さになります)ブーストなどのライブラリ。
また、「$」や「#」など、処理前に文字列から不要な文字を削除するにはどうすればよいのでしょうか?
stringstream
はこれらすべてを実行できます。
文字列を分割し、int配列に保存します。
string str = "102:330:3133:76531:451:000:12:44412";
std::replace(str.begin(), str.end(), ':', ' '); // replace ':' by ' '
vector<int> array;
stringstream ss(str);
int temp;
while (ss >> temp)
array.Push_back(temp); // done! now array={102,330,3133,76531,451,000,12,44412}
$
や#
など、処理される前の文字列から不要な文字を削除します。上記の:
を処理する方法と同じです。
Cの標準的な方法は、他の人が答えたように strtok
を使用することです。ただし、strtok
はC++
のようなものではなく、 安全でない でもありません。 C++の標準的な方法は、 std::istringstream
を使用することです
std::istringstream iss(str);
char c; // dummy character for the colon
int a[8];
iss >> a[0];
for (int i = 1; i < 8; i++)
iss >> c >> a[i];
入力が常にそのような固定数のトークンを持っている場合、sscanf
は別の簡単な解決策かもしれません
std::sscanf(str, "%d:%d:%d:%d:%d:%d:%d:%d", &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8);
以前にこのようなコードを作成する必要があり、区切り文字で文字列を分割するためのStack Overflowに関する質問を見つけました。元の質問は次のとおりです。 link 。
これをstd::stoi
とともに使用して、ベクターを構築できます。
std::vector<int> split(const std::string &s, char delim) {
std::vector<int> elems;
std::stringstream ss(s);
std::string number;
while(std::getline(ss, number, delim)) {
elems.Push_back(std::stoi(number));
}
return elems;
}
// use with:
const std::string numbers("102:330:3133:76531:451:000:12:44412");
std::vector<int> numbers = split(numbers, ':');
ここに一つの方法があります...最も賢い方法ではなく、書くのが速いです構文解析へのこのアプローチは非常に広く有用であり、学ぶのに適しています。 !(iss >> c)
は、文字列に後続の非空白文字がないことを保証します。
std::istringstream iss(the_string);
char c;
int n[8];
if (iss >> n[0] >> c && c == ':' &&
iss >> n[1] >> c && c == ':' &&
iss >> n[2] >> c && c == ':' &&
iss >> n[3] >> c && c == ':' &&
iss >> n[4] >> c && c == ':' &&
iss >> n[5] >> c && c == ':' &&
iss >> n[6] >> c && c == ':' &&
iss >> n[7] && !(iss >> c))
...
おそらくwhileループで、strtok()
を使用して文字列を分割できます。
個々の文字列を取得したら、atoi(xxx)
を使用してintに変換できます。
本当だ! elven magic はありません
そのちょっと答えた ここ も
#include <cstring>
#include <iostream>
#include<cstdlib>
#include<vector>
int main()
{
char input[100] = "102:330:3133:76531:451:000:12:44412";
char *token = std::strtok(input, ":");
std::vector<int> v;
while (token != NULL) {
v.Push_back( std::strtol( token, NULL, 10 ));
token = std::strtok(NULL, ":");
}
for(std::size_t i =0 ; i < v.size() ; ++i)
std::cout << v[i] <<std::endl;
}
デモ ここ
文字「#」と「$」を削除するには、標準アルゴリズムstd::remove_if
を使用できます。ただし、たとえば次の文字列「12#34」がある場合は、「#」を削除すると「1234」が生成されることを考慮してください。結果の文字列が「12 34」または「12:34」に見える必要がある場合は、std::remove_if
の代わりにstd::replace_if
を使用することをお勧めします。
以下に、タスクを実行するサンプルコードを示します。ヘッダーを含める必要があります
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <algorithm>
int main()
{
char s[] = "102:$$330:#3133:76531:451:000:$12:44412";
std::cout << s << std::endl;
char *p = std::remove_if( s, s + std::strlen( s ),
[]( char c ) { return ( c == '$' || c == '#' ); } );
*p = '\0';
std::cout << s << std::endl;
const size_t N = 8;
int a[N];
p = s;
for ( size_t i = 0; i < N; i++ )
{
a[i] = strtol( p, &p, 10 );
if ( *p == ':' ) ++p;
}
for ( int x : a ) std::cout << x << ' ';
std::cout << std::endl;
}
出力は
102:$$330:#3133:76531:451:000:$12:44412
102:330:3133:76531:451:000:12:44412
102 330 3133 76531 451 0 12 44412
#include <string.h>
int main ()
{
char str[] ="102:330:3133:76531:451:000:12:44412";
char * pch;
printf ("Splitting string \"%s\" into tokens:\n",str);
pch = strtok (str,":");
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, ":");
}
return 0;
}
C++ 11の正規表現機能を使用する別のソリューション。
#include <algorithm>
#include <iostream>
#include <iterator>
#include <ostream>
#include <regex>
#include <sstream>
#include <string>
#include <vector>
int main()
{
const std::string s = "102:330:3133:76531:451:000:12:44412";
// Replace each colon with a single space
const std::regex pattern(":");
const std::string r = std::regex_replace(s, pattern, " ");
std::istringstream ist(r);
std::vector<int> numbers;
std::copy(std::istream_iterator<int>(ist), std::istream_iterator<int>(),
std::back_inserter(numbers));
// We now have a vector of numbers
// Print it out
for (auto n : numbers)
{
std::cout << n << " ";
}
std::cout << std::endl;
return 0;
}