简体   繁体   English

如何在C ++中将字符串向量转换为整数向量?

[英]How do I convert vector of strings into vector of integers in C++?

I have a vector of strings. 我有一个字符串向量。 Need help figuring out how to convert it into vector of integers in order to be able to work with it arithmetically. 需要帮助搞清楚如何将其转换为整数向量,以便能够以算术方式使用它。 Thanks! 谢谢!

#include <iostream>
#include <string>
#include <vector>
using namespace std;

int main(int argc, char* argv[]) {

    vector<string> vectorOfStrings;
    vectorOfStrings.push_back("1");
    vectorOfStrings.push_back("2");
    vectorOfStrings.push_back("3");

    for (int i=0; i<vectorOfStrings.size(); i++)
    {
        cout<<vectorOfStrings.at(i)<<endl;
    }

    vector<int> vectorOfIntegers;

    //HELP NEEDED HERE
    //CONVERSION CODE from vector<string> to vector<int> 

    int sum;
    for (int i=0; i<vectorOfIntegers.size(); i++)
    {
        sum += vectorOfIntegers.at(i);
    }
    cout<<sum<<endl;
    cin.get();

    return 0;
}

There are mulitple ways of converting a string to an int. 有多种方法可以将字符串转换为int。

Solution 1: Using Legacy C functionality 解决方案1:使用Legacy C功能

int main()
{
    //char hello[5];     
    //hello = "12345";   --->This wont compile

    char hello[] = "12345";

    Printf("My number is: %d", atoi(hello)); 

    return 0;
}

Solution 2: Using lexical_cast (Most Appropriate & simplest) 解决方案2:使用lexical_cast (最合适和最简单)

int x = boost::lexical_cast<int>("12345"); 

Surround by try-catch to catch exceptions. 通过try-catch环绕以捕获异常。

Solution 3: Using C++ Streams 解决方案3:使用C++ Streams

std::string hello("123"); 
std::stringstream str(hello); 
int x;  
str >> x;  
if (!str) 
{      
   // The conversion failed.      
} 

Use boost::lexical_cast . 使用boost::lexical_cast And surround it with try-catch block. 并用try-catch块包围它。

try
{
   for (size_t i=0; i<vectorOfStrings.size(); i++)
   {
      vectorOfIntegers.push_back(boost::lexical_cast<int>(vectorOfStrings[i]));
   }
}
catch(const boost::bad_lexical_cast &)
{
    //not an integer 
}

Or you can use Boost.Spirit parser (which someone claims is faster than even atoi() ) as: 或者您可以使用Boost.Spirit解析器( 有人声称甚至比atoi() 更快 ):

int get_int(const std::string & s)
{
    int value = 0;
    std::string::const_iterator first = s.begin();
    bool r = phrase_parse(first,s.end(),*int_[ref(value)=_1], space);
    if ( !r || first != s.end()) throw "error"; 
    return value;
}

//Usage
int value = get_int("17823");
std::cout << value << std::endl; //prints 17823

The full demo using your code : http://ideone.com/DddL7 使用您的代码的完整演示: http//ideone.com/DddL7

#include <string>
#include <vector>

#include <iterator>
#include <algorithm>
#include <boost/lexical_cast.hpp>

using namespace std;

int stringToInteger(const std::string& s)
{
    return boost::lexical_cast<int>(s);
}

int main(int /*argc*/, char* /*argv*/[])
{
    vector<string> vectorOfStrings;

    // ..

    vector<int> vectorOfIntegers;
    std::transform(vectorOfStrings.begin(), vectorOfStrings.end(), std::back_inserter(vectorOfIntegers), stringToInteger);

    // ..
}

You can replace the implementation of stringToInteger(..) with your preferred conversion function. 您可以使用首选的转换函数替换stringToInteger(..)的实现。

Here is the working version made up using the above comments. 这是使用上述注释组成的工作版本。

#include <iostream>
#include <string>
#include <vector>
#include <sstream>

using namespace std;

int main(int argc, char* argv[]) {

    vector<string> vectorOfStrings;
    vectorOfStrings.push_back("1");
    vectorOfStrings.push_back("2");
    vectorOfStrings.push_back("3");

    for (int i=0; i<vectorOfStrings.size(); i++)
    {
        cout<<vectorOfStrings.at(i)<<endl;
    }

    vector<int> vectorOfIntegers;
    int x;
    for (int i=0; i<vectorOfStrings.size(); i++)
    {
        stringstream str(vectorOfStrings.at(i));
        str >> x;
        vectorOfIntegers.push_back(x);
    }

    int sum = 0;
    for (int i=0; i<vectorOfIntegers.size(); i++)
    {
        sum += vectorOfIntegers.at(i);
    }
    cout<<sum<<endl;
    cin.get();

    return 0;
}

What about: 关于什么:

#include <algorithm>
#include <boost/lexical_cast.hpp>

template<typename C1, typename C2>
void castContainer(const C1& source, C2& destination)
{
    typedef typename C1::value_type source_type;
    typedef typename C2::value_type destination_type;
    destination.resize(source.size());
    std::transform(source.begin(), source.end(), destination.begin(), boost::lexical_cast<destination_type, source_type>);
}

It can convert vector<string> into vector<int>, and also other container<T1> into container2<T2>, eg: list -> list. 它可以将vector <string>转换为vector <int>,并将其他容器<T1>转换为container2 <T2>,例如:list - > list。

Full code: 完整代码:

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <string>
#include <boost/lexical_cast.hpp>

template<typename C1, typename C2>
void castContainer(const C1& source, C2& destination)
{
    typedef typename C1::value_type source_type;
    typedef typename C2::value_type destination_type;
    destination.resize(source.size());
    std::transform(source.begin(), source.end(), destination.begin(), boost::lexical_cast<destination_type, source_type>);
}

template<typename T, typename T2>
std::vector<T>& operator<<(std::vector<T>& v, T2 t)
{
    v.push_back(T(t));
    return v;
}

main(int argc, char *argv[])
{   
    std::vector<std::string> v1;
    v1 << "11" << "22" << "33" << "44";
    std::cout << "vector<string>: ";
    std::copy(v1.begin(), v1.end(), std::ostream_iterator<std::string>(std::cout, ", "));
    std::cout << std::endl;

    std::vector<int> v2;
    castContainer(v1, v2);

    std::cout << "vector<int>: ";
    std::copy(v2.begin(), v2.end(), std::ostream_iterator<int>(std::cout, ", "));
    std::cout << std::endl;
}

There are two independent tasks. 有两个独立的任务。

  1. Convert a single string to an integer 将单个字符串转换为整数
  2. Having something that can convert from A to B, convert std::vector<A> to std::vector<B> 有一些可以从A转换为B的东西,将std::vector<A>转换为std::vector<B>

I suggest you try to do them separately, and then combine the results. 我建议你单独尝试,然后结合结果。 If one of these tasks proves difficult, you will be able to ask a more focused question. 如果其中一项任务难以证明,您将能够提出更具针对性的问题。

The most general way to convert strings to integers is with stringstream and a function template. 将字符串转换为整数的最常用方法是使用stringstream和函数模板。 You can optionally set the base for the conversion if you're dealing with hexadecimal. 如果您正在处理十六进制,则可以选择设置转换的基数。 The boost library would also be helpful in your example. 在您的示例中,boost库也会有所帮助。

#include <iostream>
#include <string>
#include <vector>

#include <sstream>
#include <stdexcept>
#include <boost/static_assert.hpp>
#include <boost/foreach.hpp>

/******************************************************************************
 * Handy string to type conversion
 * First parameter is the string to convert
 * Second optional parameter is the number base, e.g. std::hex
 * 
 * Because this is a function template, the compiler will instantiate one
 * instance of the function per type
 *****************************************************************************/
// the std::dec thingy is actually a function, so extra glue required.
typedef std::ios_base& (*ios_base_fn)( std::ios_base& str );
template <class T>
T strtotype( const std::string& s, ios_base_fn base = std::dec )
{
    // C++ can't convert 8-bit values, they are *always* treated
    // as characters. :(  At least warn the user.
    // this gives a cryptic error message, but better than nothing.
    BOOST_STATIC_ASSERT( sizeof(T) > 1 );

    T val;
    std::istringstream iss(s);
    iss >> base >> val;
    if( iss.fail() )
        throw std::runtime_error( "Error: strtotype(): Can't convert string '" + s + "' to numeric value" );
    return val;
}

using namespace std;

int main(int argc, char* argv[]) {

    vector<string> vectorOfStrings;
    vectorOfStrings.push_back("1");
    vectorOfStrings.push_back("2");
    vectorOfStrings.push_back("3");

    for (int i=0; i<vectorOfStrings.size(); i++)
    {
        cout<<vectorOfStrings.at(i)<<endl;
    }

    vector<int> vectorOfIntegers;

    for( size_t i = 0; i < vectorOfStrings.size(); i++ )
        vectorOfIntegers.push_back( strtotype<int>( vectorOfStrings[i] ));

    // or better yet, use boost_foreach
    BOOST_FOREACH( const string& s, vectorOfStrings )
        vectorOfIntegers.push_back( strtotype<int>( s ));

    int sum;
    for (int i=0; i<vectorOfIntegers.size(); i++)
    {
        sum += vectorOfIntegers.at(i);
    }
    cout<<sum<<endl;
    cin.get();

    return 0;
}

If you don't want or can't use boost, you can remove the sizeof() check in strtotype. 如果您不想或不能使用boost,可以删除stofotype中的sizeof()检查。 However, be careful never to try to convert to strings to individual bytes. 但是,请注意永远不要尝试将字符串转换为单个字节。 Doing so will fail silently by only converting the first nibble of the byte. 只需转换字节的第一个半字节,这样做会无声地失败。

If you're suing GNU tools, then compile like so: 如果您正在使用GNU工具,那么编译如下:

 g++ -Wall -O3 -I /path/to/boost/include main.cpp

or, if you delete the boost related bits: 或者,如果删除与增强相关的位:

 g++ -Wall -O3 main.cpp 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM