【问题标题】:C++ initializing vector with iteratorsC++ 使用迭代器初始化向量
【发布时间】:2016-06-20 13:44:17
【问题描述】:

我正在尝试将无符号字符文件读入向量。我这样做的稍微迂回的方法是创建一个输入文件流,将该数据读入一个字符串流,并使用字符串流的内容初始化一个向量。可能有更好的方法可以做到这一点,而我现有的代码使用某些文件会导致分段错误。

string file_name = "output/comp" + to_string(start_id) + ".xml";

if( !file_exists(file_name))
{
    cout << "File could not be found." << endl;
    return 0;
}

ifstream ifs(file_name);
stringstream ss;
ss << ifs.rdbuf();
ss >> noskipws;

vector<unsigned char> raw_data(ss.str().begin(), ss.str().end());

我已经包含了所有必要的标题和using 声明,file_exists() 返回一个布尔值,指示文件是否存在。

我的问题是:为什么上面的代码不正确,正确实现相同目标的最佳方法是什么?

【问题讨论】:

  • 可能需要在文件打开方式中添加binary

标签: c++ string vector ifstream stringstream


【解决方案1】:

std::stringstream::str() 返回一个std::string。也就是说,它是一个临时字符串。

所以ss.str().begin()返回一个临时字符串的开始迭代器,ss.str().end()返回一个不同临时字符串的结束迭代器,因为两个ss.str()调用都返回不同 临时字符串。您不能在不同对象之间混合使用迭代器!

要解决此问题,请使用一个字符串:

std::string str = ss.str();

现在只需传递str.begin()str.end()

【讨论】:

    【解决方案2】:

    问题

    vector<unsigned char> raw_data(ss.str().begin(), ss.str().end());
    

    str() 返回一个临时字符串。这意味着您用于beginstring 与您用于endstring 不同。由于迭代器不引用相同的string,因此您不能将它们一起使用。

    我们可以使用istream_iterators 直接将文件读入向量,而不是使用strignstream

    std::ifstream ifs(file_name);
    std::istream_iterator<unsigned char> start(ifs), end;
    std::vector<unsigned char> raw_data(start, end);
    

    【讨论】:

      【解决方案3】:

      我不确定为什么会导致段错误,可能是字符串流中的某些东西,但是使用 c++11,一旦你有任何 istream 派生,就很容易将文件读入字符串:

      std::string readFileAsString(std::istream& stream)
      {
           return std::string(std::istreambuf_iterator<char>(stream), std::istreambuf_iterator<char>());
      }
      

      编辑对不起,我忘了你想要最后的字节

      return std::vector<char>(std::istreambuf_iterator<char>(stream), std::istreambuf_iterator<char>());
      

      【讨论】:

        猜你喜欢
        • 2012-02-09
        • 1970-01-01
        • 2020-09-27
        • 2017-01-03
        • 1970-01-01
        • 2012-10-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多