C++ 如何通过分隔符将字符串拆分为数组?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/890164/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I split a string by a delimiter into an array?
提问by Babiker
I am new to programming. I have been trying to write a function in C++ that explodes the contents of a string into a string array at a given parameter, example:
我是编程新手。我一直在尝试用 C++ 编写一个函数,它将字符串的内容分解为给定参数的字符串数组,例如:
string str = "___this_ is__ th_e str__ing we__ will use__";
should return string array:
应该返回字符串数组:
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'
I can tokenize the string just fine, but the hardest part for me is how can i specify the number of elements in stringArray before assigning it the current string toke and also how to return stringArray from the function.
我可以很好地标记字符串,但对我来说最困难的部分是如何在将 stringArray 分配给当前字符串标记之前指定 stringArray 中的元素数量以及如何从函数返回 stringArray。
Would someone show me how to write the function?
有人会告诉我如何编写函数吗?
Edit1:I don't necessarily need the results to been in string array just any container that i can call as a regular variable with some sort of indexing.
Edit1:我不一定需要将结果放在字符串数组中,只是我可以将其作为具有某种索引的常规变量调用的任何容器。
回答by Eric Scrivner
Here's my first attempt at this using vectors and strings:
这是我第一次尝试使用向量和字符串:
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;
}
Hopefully this gives you some sort of idea of how to go about this. On your example string it returns the correct results with this test code:
希望这能给你一些关于如何去做的想法。在您的示例字符串中,它使用以下测试代码返回正确的结果:
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;
}
回答by Martin York
Using STL (sorry no compiler not tested)
使用 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.
}
}
// or define a token
// 或定义一个令牌
#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)
);
}
回答by Ouadie
It works for me :
这个对我有用 :
#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;
}
source :http://www.zedwood.com/article/106/cpp-explode-function
来源:http : //www.zedwood.com/article/106/cpp-explode-function
回答by dmckee --- ex-moderator kitten
If you insist on making stringArray
an array as oppossed to a std::vector<>
(which would be the right thing to do) you have to either:
如果您坚持要制作stringArray
一个与 a 相对的数组std::vector<>
(这是正确的做法),您必须:
- Make two passes (one to count, you see)
- Implement a dynamic array yourself.
- 进行两次传球(一次计数,你看)
- 自己实现一个动态数组。
Using a vector is easier vector::push_back()
appends new stuff to the end. So:
使用向量更容易vector::push_back()
将新内容附加到末尾。所以:
vector* explode(string s){
vector<string> *v = new vector<string>
//...
// in a loop
v->push_back(string_fragment);
//...
return v;
}
Not needed after allLeft in for completeness.
毕竟不需要为了完整起见。
To return the array of strings you use char **
.
要返回您使用的字符串数组char **
。
As in
如
char ** explode(const char *in){
...
}
BTW-- How will the calling function know how many elements are in the returned array? You'll have to solve that too. Use std::vector<>
unless you are constrained by outside forces...
顺便说一句——调用函数如何知道返回数组中有多少元素?你也必须解决这个问题。std::vector<>
除非您受到外力约束,否则请使用...
回答by Jem
You can use a vector of string (std::vector<std::string>
), append each token to it with push_back, and then return it from your tokenize function.
您可以使用 string (std::vector<std::string>
)向量,使用 push_back 将每个标记附加到它,然后从您的标记化函数返回它。
回答by workmad3
Use std::vector as a dynamic array and return that as your result.
使用 std::vector 作为动态数组并将其作为结果返回。
回答by user79755
Perhaps you should use a list instead of an array. That way you would not need to know the number of elements ahead of time. You may also consider using the STL containers.
也许您应该使用列表而不是数组。这样你就不需要提前知道元素的数量。您也可以考虑使用 STL 容器。
回答by JasonRShaver
Wait until your data structures class and then code it with a linked list. If it is for homework though, you may be able to get away with just initing the array be very large.
等到您的数据结构类,然后使用链表对其进行编码。但是,如果是为了作业,您可能只需将数组初始化为非常大就可以逃脱。
回答by Paulo Lellis
The code below:
下面的代码:
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;
}
Outputs
输出
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~
回答by Vivek
Here is my cooked up code (complete). May be it's useful for some with the same need.
这是我编写的代码(完整)。可能对一些有相同需求的人有用。
#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";
}
Cheers!!
干杯!!