简体   繁体   English

C ++用迭代器初始化向量

[英]C++ initializing vector with iterators

I am attempting to read a file of unsigned characters into a vector. 我正在尝试将无符号字符文件读入向量。 My slightly roundabout way of doing this is by creating an input file stream, reading that data into a stringstream, and initializing a vector using the contents of the stringstream. 我这样做的方式有点round回,方法是创建一个输入文件流,将该数据读入字符串流,并使用字符串流的内容初始化向量。 There is probably a much better way to do this, and my existing code causes a segmentation fault using certain files. 可能有更好的方法来执行此操作,并且我现有的代码使用某些文件会导致分段错误。

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());

I have included all the necessary headers and using declarations, and file_exists() returns a boolean value indicating whether or not the file exists. 我已经包含了所有必需的头文件并using声明,并且file_exists()返回一个布尔值,指示该文件是否存在。

My question is this: Why is the above code incorrect, and what is the best method for correctly accomplishing the same objective? 我的问题是:为什么上面的代码不正确?正确完成同一目标的最佳方法是什么?

std::stringstream::str() returns a std::string . std::stringstream::str()返回一个std::string That is, it's a temporary string. 也就是说,这是一个临时字符串。

So ss.str().begin() returns the beginning iterator for a temporary string, and ss.str().end() returns the ending iterator of a different temporary string, because both ss.str() calls are returning different temporary strings. 因此ss.str().begin()返回临时字符串的开始迭代器,而ss.str().end()返回不同临时字符串的结束迭代器,因为两个ss.str()调用都返回不同的字符串临时字符串。 You can't mix iterators between different objects! 您不能在不同对象之间混合迭代器!

To fix this, use one string: 要解决此问题,请使用一个字符串:

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

And now just pass str.begin() and str.end() . 现在只需传递str.begin()str.end()

The problem with 问题所在

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

is that str() returns a temporary string. str()返回一个临时字符串。 This means the string you use for begin is not the same string you use for end . 这意味着string您使用begin是不一样的string您使用end Since the iterators do not refer to the same string you cannot use them together. 由于迭代器没有引用相同的string ,因此无法一起使用。

Instead of using a strignstream we can read the file directly into the vector using istream_iterator s like 无需使用strignstream我们可以使用istream_iterator将文件直接读取到向量中,例如

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

i'm not exactly sure why that would cause a segfault, perhaps something in string stream, but with c++11 it's very easy to read a file into a string once you have any istream derivative: 我不确定为什么会导致段错误,也许是字符串流中的某些内容,但是使用c ++ 11,一旦有了任何istream派生,就很容易将文件读入字符串中:

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

edit sorry, I forgot you wanted the bytes at the end 编辑对不起,我忘了你想要结尾处的字节

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

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

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