如何将一个字符串通过分隔符分割成一个数组?
我是编程新手。我一直试图用C++函数在给定参数爆炸字符串的内容转换为字符串数组,例如:如何将一个字符串通过分隔符分割成一个数组?
string str = "___this_ is__ th_e str__ing we__ will use__";
应返回字符串数组:
cout << stringArray[0]; // 'this'
cout << stringArray[1]; // ' is'
cout << stringArray[2]; // ' th'
cout << stringArray[3]; // 'e str'
cout << stringArray[4]; // 'ing we'
cout << stringArray[5]; // ' will use'
我可以令牌化该字符串很好,但对我来说最难的部分是我如何指定stringArray中的元素数量,然后将其分配给当前字符串toke以及如何从函数返回stringArray。
有人会告诉我如何编写函数?
编辑1:我不一定需要结果在字符串数组中,只是任何容器,我可以作为一种常规变量与某种索引调用。
这是我在这个使用向量和字符串的第一次尝试:
vector<string> explode(const string& str, const char& ch) {
string next;
vector<string> result;
// For each character in the string
for (string::const_iterator it = str.begin(); it != str.end(); it++) {
// If we've hit the terminal character
if (*it == ch) {
// If we have some characters accumulated
if (!next.empty()) {
// Add them to the result vector
result.push_back(next);
next.clear();
}
} else {
// Accumulate the next character into the sequence
next += *it;
}
}
if (!next.empty())
result.push_back(next);
return result;
}
但愿这给你某种如何去这个想法的。在您的例子字符串,返回与此测试代码正确的结果:
int main (int, char const **) {
std::string blah = "___this_ is__ th_e str__ing we__ will use__";
std::vector<std::string> result = explode(blah, '_');
for (size_t i = 0; i < result.size(); i++) {
cout << "\"" << result[i] << "\"" << endl;
}
return 0;
}
如果你坚持做stringArray
数组作为oppossed到std::vector<>
(这是做正确的事),你必须要么:
- 做两遍(一数,你看)
- 你自己实现一个动态数组。
使用矢量更容易vector::push_back()
追加新的东西到最后。所以:
vector* explode(string s){
vector<string> *v = new vector<string>
//...
// in a loop
v->push_back(string_fragment);
//...
return v;
}
留下的完整性所有后则不需要。
要返回使用char **
的字符串数组。
正如
char ** explode(const char *in){
...
}
BTW--如何调用函数知道有多少元素的返回数组中?你也必须解决这个问题。使用std::vector<>
,除非受到外力的限制...
v-> push_back(string_fragment); – ralphtheninja 2009-05-20 21:11:15
您可以使用字符串(std::vector<std::string>
)的向量,使用push_back将每个令牌附加到它,然后从您的tokenize函数中返回它。
使用std :: vector作为动态数组,并将其作为结果返回。
也许你应该使用列表而不是数组。这样你就不需要提前知道元素的数量。你也可以考虑使用STL容器。
使用STL(抱歉,没有编译器未测试)
#include <vector>
#include <string>
#include <sstream>
int main()
{
std::vector<std::string> result;
std::string str = "___this_ is__ th_e str__ing we__ will use__";
std::stringstream data(str);
std::string line;
while(std::getline(data,line,'_'))
{
result.push_back(line); // Note: You may get a couple of blank lines
// When multiple underscores are beside each other.
}
}
//或定义令牌
#include <vector>
#include <string>
#include <iterator>
#include <algorithm>
#include <sstream>
struct Token: public std::string // Yes I know this is nasty.
{ // But it is just to demosntrate the principle.
};
std::istream& operator>>(std::istream& s,Token& t)
{
std::getline(s,t,'_');
// ***
// Remove extra '_' characters from the stream.
char c;
while(s && ((c = s.get()) != '_')) {/*Do Nothing*/}
if (s)
{
s.unget(); // Put back the last char as it is not '_'
}
return s;
}
int main()
{
std::vector<std::string> result;
std::string str = "___this_ is__ th_e str__ing we__ will use__";
std::stringstream data(str);
std::copy(std::istream_iterator<Token>(data),
std::istream_iterator<Token>()
std::back_inserter(result)
);
}
等到你的数据结构类,然后用链表进行编码。如果它是为了作业而做的,那么你可能能够逃脱,只是启动数组非常大。
下面的代码:
template <typename OutputIterator>
int explode(const string &s, const char c, OutputIterator output) {
stringstream data(s);
string line;
int i=0;
while(std::getline(data,line,c)) { *output++ = line; i++; }
return i;
}
int main(...) {
string test="H:AMBV4:2:182.45:182.45:182.45:182.45:182.41:32:17700:3229365:201008121711:0";
cout << test << endl;
vector<string> event;
**This is the main call**
int evts = explode(test,':', back_inserter(event));
for (int k=0; k<evts; k++)
cout << event[k] << "~";
cout << endl;
}
输出
H:AMBV4:2:182.45:182.45:182.45:182.45:182.41:32:17700:3229365:201008121711:0
H~AMBV4~2~182.45~182.45~182.45~182.45~182.41~32~17700~3229365~201008121711~0~
它为我的作品:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
vector<string> explode(const string &delimiter, const string &explodeme);
int main(int argc, char *argv[])
{
string str = "I have a lovely bunch of cocoa nuts";
cout<<str<<endl;
vector<string> v = explode(" ", str);
for(int i=0; i<v.size(); i++)
cout <<i << " ["<< v[i] <<"] " <<endl;
}
vector<string> explode(const string &delimiter, const string &str)
{
vector<string> arr;
int strleng = str.length();
int delleng = delimiter.length();
if (delleng==0)
return arr;//no change
int i=0;
int k=0;
while(i<strleng)
{
int j=0;
while (i+j<strleng && j<delleng && str[i+j]==delimiter[j])
j++;
if (j==delleng)//found delimiter
{
arr.push_back( str.substr(k, i-k));
i+=delleng;
k=i;
}
else
{
i++;
}
}
arr.push_back( str.substr(k, i-k));
return arr;
}
这是我煮熟的代码(完整)。对于某些需求相同的用户可能会有用。
#include <string>
#include <iostream>
#include <sstream>
#include <vector>
using namespace std;
int main(){
std::string s = "scott:tiger:mushroom";
std::string delimiter = ":";
std::vector<std::string> outputArr;
size_t pos = 0;
std::string token;
while ((pos = s.find(delimiter)) != std::string::npos) {
token = s.substr(0, pos);
s.erase(0, pos + delimiter.length());
outputArr.push_back(token);
}
outputArr.push_back(s);
// Printing Array to see the results
std::cout<<"====================================================================================\n";
for (int i=0;i<outputArr.size();i++){
std::cout<<outputArr[i]<<"\n";
}
std::cout<<"====================================================================================\n";
}
干杯!
我认为我写了一个更简单的解决方案。
std::vector<std::string> explode(const std::string& string, const char delimiter) {
std::vector<std::string> result;
unsigned int start = 0, pos = 0;
while (pos != string.length()) {
if (string.at(pos) == delimiter || pos + 1 == string.length()) {
unsigned int size = (pos - start) + ((pos + 1) == string.length() ? 1 : 0);
if (size != 0) { // Make this 'if' as a option? like a parameter with removeEmptyString?
result.push_back(string.substr(start, size));
}
start = pos + 1;
}
pos++;
}
return std::move(result);
}
这为我工作:
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
using namespace std;
vector<string> split(string str, char delimiter) {
vector<string> internal;
stringstream ss(str); // Turn the string into a stream.
string tok;
while(getline(ss, tok, delimiter)) {
internal.push_back(tok);
}
return internal;
}
int main(int argc, char **argv) {
string myCSV = "one,two,three,four";
vector<string> sep = split(myCSV, ',');
// If using C++11 (which I recommend)
/* for(string t : sep)
* cout << t << endl;
*/
for(int i = 0; i < sep.size(); ++i)
cout << sep[i] << endl;
}
来源:http://code.runnable.com/VHb0hWMZp-ws1gAr/splitting-a-string-into-a-vector-for-c%2B%2B
功课,或许?没问题,当然,但我从回答作业问题的人群不同... – dmckee 2009-05-20 20:59:53
重复:http://stackoverflow.com/questions/53849/how-do-i-tokenize-a-string-in-c – lothar 2009-05-20 21:08:43
@Iharhar这里的答案似乎更有效率。 – Arnthor 2011-10-16 14:49:44