我有一个逗号分隔的整数,我想将它们存储在std::vector<int>
中。目前我手动完成它。是否有任何内置功能可以完成上述功能?
我很着急,忘了详细说明
实际上我有包含CSv的字符串(确切地说是Unicode字符串),例如“1,2,3,4,5”
现在我想将它们存储在std::vector<int>
中,所以在上面的例子中,我的向量将有五个元素被推入其中。目前我正在通过手动进行此操作,但它的速度很慢以及该代码存在很多混乱
答案 0 :(得分:4)
这可能不是最有效的方法,但是这里有一种方法可以使用TR1正则表达式功能(我在这个示例中也使用了C ++ 0x lambda语法,但显然它也可以在没有它的情况下完成):< / p>
#include <iostream>
#include <algorithm>
#include <vector>
#include <regex>
#include <iterator>
#include <cstdlib>
std::vector<int> GetList(const std::wstring &input)
{
std::vector<int> result;
std::wsregex_iterator::regex_type rex(L"(\\d+)(,|$)");
std::wsregex_iterator it(input.begin(), input.end(), rex);
std::transform(it, std::wsregex_iterator(), std::back_inserter(result),
[] (const std::wsregex_iterator::value_type &m)
{ return std::wcstol(m[1].str().c_str(), nullptr, 10); });
return result;
}
答案 1 :(得分:3)
为了简单起见,你可以纯粹在STL中使用它(易于阅读,不需要复杂的库),编码速度快,但执行速度不是最快的(尽管你可以调整一下,就像在矢量中预留空间一样:
std::vector<int> GetValues(std::wstring s, wchar_t delim)
{
std::vector<int> v;
std::wstring i;
std::wstringstream ss(s);
while(std::getline(ss,i,delim))
{
std::wstringstream c(i);
int x;
c >> x;
v.push_back(x);
}
return v;
}
(不转发(&&
)或atoi以保持代码可移植。)
答案 2 :(得分:2)
遗憾的是,STL不允许您在分隔符上拆分字符串。您可以使用boost来执行此操作:(需要最新的C ++编译器,如MSVC 2010或GCC 4.5)
#include <vector>
#include <string>
#include <algorithm>
#include <iostream>
#include <iterator>
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
using namespace std;
int main(int argc, char** argv)
{
string input = "1,2,3,4";
vector<string> strs;
boost::split(strs, input, boost::is_any_of(","));
vector<int> result;
transform(
strs.begin(), strs.end(), back_inserter(result),
[](const string& s) -> int { return boost::lexical_cast<int>(s); }
);
for (auto i = result.begin(); i != result.end(); ++i)
cout << *i << endl;
}
答案 3 :(得分:2)
快速和脏选项是使用C字符串库strtok()函数和atoi():
void Split(char * string, std::vector<int>& intVec)
{
char * pNext = strtok(string, ",");
while (pNext != NULL)
{
intVec.push_back(atoi(pNext));
pNext = strtok(NULL, ",");
}
}
根据需要插入您自己的输入数据验证。
请参阅:
http://www.cplusplus.com/reference/clibrary/cstring/strtok/
http://www.cplusplus.com/reference/clibrary/cstdlib/atoi/
以及宽字符串版本:
http://msdn.microsoft.com/en-us/library/2c8d19sb%28v=vs.71%29.aspx
http://msdn.microsoft.com/en-us/library/aa273408%28v=vs.60%29.aspx
编辑:
请注意,strtok()
会修改原始字符串,因此如果需要,请传递副本。
答案 4 :(得分:1)
试试这个:
它将读取由任何字符(您选择)分隔的任何类型(可以使用&gt;&gt;读取)
注意:读取对象后,对象和分隔符之间应该只有空格。因此对于像ObjectSepReader<std::string, ','>
这样的东西,它将读取由','。
这使我们可以很容易地使用我们的标准算法:
#include <vector>
#include <sstream>
#include <iostream>
#include <iterator>
#include <algorithm>
int main()
{
std::stringstream data("1,2,3,4,5,6,7,8,9");
std::vector<int> vdata;
// Read the data from a stream
std::copy(std::istream_iterator<ObjectSepReader<int, ','> >(data),
std::istream_iterator<ObjectSepReader<int, ','> >(),
std::back_inserter(vdata)
);
// Copy data to output for testing
std::copy(vdata.begin(), vdata.end(), std::ostream_iterator<int>(std::cout," "));
}
让它发挥作用的秘密课程。
template<typename T,char S>
struct ObjectSepReader
{
T value;
operator T const&() const {return value;}
};
template<typename T,char S>
std::istream& operator>>(std::istream& stream, ObjectSepReader<T,S>& data)
{
char terminator;
std::string line;
std::getline(stream, line, S);
std::stringstream linestream(line + ':');
if (!(linestream >> data.value >> terminator) || (linestream.tellg() != line.size()+1) || (terminator != ':'))
{ stream.setstate(std::ios::badbit);
}
return stream;
}
答案 5 :(得分:0)
就个人而言,我会创建一个结构并让向量包含结构的实例。 像这样:
struct ExampleStruct
{
int a;
int b;
int c;
};
vector<ExampleStruct> structVec;
答案 6 :(得分:0)
这个怎么样?
#include <string>
#include <vector>
#include <functional>
#include <algorithm>
#include <iostream>
struct PickIntFunc
{
PickIntFunc(std::vector<int>& vecInt): _vecInt(vecInt),_pBegin(0){}
char operator () (const char& aChar)
{
if(aChar == ',' || aChar == 0)
{
_vecInt.push_back(atoi(std::string(_pBegin,&aChar).c_str()));
_pBegin = 0;
}
else
{
if(_pBegin == 0)
{
_pBegin = &aChar;
}
}
return aChar;
}
const char* _pBegin;
std::vector<int>& _vecInt;
};
int _tmain(int argc, _TCHAR* argv[])
{
std::vector<int> vecInt;
char intStr[] = "1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20";
std::for_each(intStr,intStr+sizeof(intStr),PickIntFunc(vecInt));
// Now test it
std::for_each(vecInt.begin(),vecInt.end(), [] (int i) { std::cout << i << std::endl;});
return 0;
}