C ++ newbie:模板函数问题 - 从文本文件中获取字符串和数值数据,将其放在向量中

时间:2011-02-07 14:06:25

标签: c++ templates stream

我是新手。我试图编写一个模板函数,从文本文件中获取字符串AND数值数据(例如,douubles),然后将其放入向量中。向量的每个元素都是不同的名称或数字。

上周我询问过载或模板是否最适合这种情况。我想使用模板方法,其中结果向量(我想要的)传递给函数以提供模板参数T.但是我遇到了问题。如果有人可以提供帮助,我将不胜感激!代码如下,然后是我得到的错误。

//我的代码:

template<typename T>
void readFile( const std::string& name, const std::string& find, std::vector<T>& results ){
    std::ifstream file( name.c_str( ) );
    std::string   line;

    while( std::getline( file, line ) )
    {
        if( line == find )
        {
            std::getline( file, line );
            line.erase(remove( line.begin(), line.end(), '\'' ), line.end() );
            std::istringstream streamLine( line );

            results = std::vector<T>( std::istream_iterator<T>(streamLine), std::istream_iterator<T>() );
        }
    }
}

在main()中调用:

readFile( name, "label", results );

我得到的错误如下。我不明白函数调用如何与定义不匹配。对任何愚蠢的错误提前道歉!

error: no matching function for call to 
'std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >,
std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >
::resize(std::basic_string<char, std::char_traits<char>, std::allocator<char> >&)'

奇怪的是,如果我让函数返回向量“result”而不是void,那么事情似乎有效。这就是我的意思:

std::vector<T> readFile( const std::string& name, const std::string& find, std::vector<T>& results )

在函数定义中使用return语句:

return std::vector<T>( std::istream_iterator<T>(streamLine), std::istream_iterator<T>() );

但这样做似乎很笨拙/糟糕。我原以为使用引用会更好。即使它不是更好,我很想知道为什么第一种方法(带有void)不起作用。

任何提示都将不胜感激!

2 个答案:

答案 0 :(得分:1)

我不得不做一些工作来使这个完全可编辑的代码片段。以下是我提出的建议:

#include <string>
#include <vector>
#include <istream>
#include <fstream>
#include <iterator>
#include <sstream>
#include <algorithm>

template<typename T>
void readFile(const std::string& name,
              const std::string& find,
              std::vector<T>& results )
{
   std::ifstream file( name.c_str( ) );
   std::string   line;

   while( std::getline( file, line ) )
   {
      if( line == find )
      {
         std::getline( file, line );
         line.erase(remove( line.begin(), line.end(), '\'' ), line.end() );
         std::istringstream streamLine( line );

         results = std::vector<T>( std::istream_iterator<T>(streamLine),
                                   std::istream_iterator<T>() );
      }
   }
}

void do_it_with_strings(std::vector<std::string> &results)
{
   readFile("fred", "barney", results);
}

此代码段与gcc 4.5.1编译得很好。 name函数中resultsmain的确切类型是什么?此外,问题似乎是调用向量的resize函数。您似乎没有在代码中直接执行此操作,尽管向量构造函数或赋值运算符可能在内部执行此操作。

但无论如何,我不建议你以这种方式编写代码。我建议你这样做:

#include <string>
#include <vector>
#include <istream>
#include <fstream>
#include <iterator>
#include <sstream>
#include <algorithm>

template<typename T>
std::vector<T> readFile(const std::string& name, const std::string& find )
{
   std::ifstream file( name.c_str( ) );
   std::string   line;

   while( std::getline( file, line ) )
   {
      if( line == find )
      {
         std::getline( file, line );
         line.erase(remove( line.begin(), line.end(), '\'' ), line.end() );
         std::istringstream streamLine( line );

         return std::vector<T>( std::istream_iterator<T>(streamLine),
                                std::istream_iterator<T>() );
      }
   }
   return std::vector<T>();
}

void do_it_with_strings(std::vector<std::string> &results)
{
   results = readFile<std::string>("fred", "barney");
}

在这样的函数中,我认为最好是在调用函数时明确说明您期望读取的类型,而不是根据传入的vector的类型隐式确定它。

答案 1 :(得分:1)

这是一段代码,可以从文件中获取字符串或数值:

#include <fstream>
#include <vector>
#include <iterator>
#include <algorithm>

template<typename T>
void read_values(const std::string& filename, std::vector<T>& coll)
{
    std::fstream file(filename);

    std::copy (std::istream_iterator<T>(file),    
               std::istream_iterator<T>(),
               back_inserter(coll));

    std::sort(coll.begin(), coll.end());

    coll.erase(std::unique(coll.begin(), coll.end()), coll.end());
}

int main(int argc, char* argv[])
{
    std::vector<int> values;
    read_values("C:\\example.txt", values);

    return 0;
}

如果你想改为读取字符串值,你只需要提供一个std :: vector std :: string来传递给模板函数。