c++ Split string by a character?
如何用"EDOCX1"〔1〕字符拆分"EDOCX1"〔0〕这样的字符串,最好将所有的数字放入一个int数组(数字序列总是8长),而不使用外部库,如boost。
另外,我想知道如何在处理字符串之前从字符串中删除不需要的字符,例如"$"和""?
拆分字符串并存储到int数组中:
1 2 3 4 5 6 7 8 | 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语言中的标准方法是像其他人回答的那样使用
1 2 3 4 5 6 | 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]; |
如果输入总是有固定数量的令牌,那么
1 | std::sscanf(str,"%d:%d:%d:%d:%d:%d:%d:%d", &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8); |
我以前不得不写一些这样的代码,在堆栈溢出中发现了一个问题,即用分隔符拆分字符串。这是最初的问题:链接。
您可以将它与
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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, ':'); |
这是一个有效的Ideone示例。
这是一条路…不是最聪明的,但写起来很快(8次重复几乎保证了一个循环)。这种解析方法非常有用,学习起来非常好。
1 2 3 4 5 6 7 8 9 10 11 12 | 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)) ... |
要删除字符""和"$",可以使用标准算法
下面是执行任务的示例代码。您需要包含标题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | #include <iostream> #include <cstdlib> #include <cstring> #include 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; } |
输出是
1 2 3 | 102:$$330:#3133:76531:451:000:$12:44412 102:330:3133:76531:451:000:12:44412 102 330 3133 76531 451 0 12 44412 |
在C++ 11中使用正则表达式特征的另一种解决方案。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | #include #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; } |
包括
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #include <string.h> int main () { char str[] ="102:330:3133:76531:451:000:12:44412"; char * pch; printf ("Splitting string "%s" into tokens: ",str); pch = strtok (str,":"); while (pch != NULL) { printf ("%s ",pch); pch = strtok (NULL,":"); } return 0; } |
真的!没有精灵魔法
它也有点回答这里
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #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; } |
这里演示
您可以使用
当您得到单个字符串时,就可以使用