C ++ ifstream :: read () and C arrays

It seems like the general consensus is that C arrays are bad and that using smarter alternatives like vectors or C ++ strings is the way to go. There is no problem.

Having said that, why is the read() member of the ifstream input in char* ... The question is: can I enter a byte vector using STL?

A related bonus question: Do you often check ios::badbit and ios::failbit , especially if you work with a dynamically allocated C string inside this area? Are you freeing the C string in catch() ?

Thanks for reading.

+4
source share
2 answers

You can read directly into the selected vector (I have no way to compile this from here so that there can be typos or transposed parameters, etc.), but the idea is correct.

 vector<char> data; data.resize(100); // Read 100 characters into the storage of data thing.read(&data[0], 100); 
+2
source

Having said that, why the read () member of the ifstream input is bound to char * ...

It was a design. Not necessarily the smartest.

The question arises: can I somehow enter a byte vector

The underlying storage for std::vector<char> guaranteed to be contiguous (i.e. one block of memory), so yes. To use ifstream::read , you must (a) make sure that the size of the vector is large enough (using .resize() - not .reserve() ! This is because the vector is not aware of the data you are reading its unused capacity and update its size ), and then (b) get a pointer to the starting element of the vector (for example, using &v.front() or &(v[0]) ).

If you do not want to pre-format the vector, then there are more complex methods that you can use, including iterator types and standard library algorithms. They have the advantage that you can easily read the entire file into a vector without having to check the file length first (and standard tricks for checking the file length may not be as reliable as you think!).

It looks something like this:

 #include <iterator> #include <algorithm> // in addition to what you already have. // ... std::ifstream ifs; std::vector v; // ... std::istreambuf_iterator<char> begin(ifs), end; std::copy(begin, end, std::back_inserter(v)); 

Of course, the byte vector is not a string. But you can do the same with std::string - the std::back_inserter is smart enough to create the appropriate type of iterator for any supplied type that provides .push_back() , which executes both string and vector . This is the magic of templates. :)

using only STL?

I'm confused. I thought we were talking about the standard C ++ library. What kind of STL are you talking about?

A related bonus question: often you check ios :: badbit and ios :: failbit

No; I usually write code in such a way that I can just check the result of the read operation directly. See http://www.parashift.com/c++-faq-lite/input-output.html#faq-15.4 for an example / discussion.

especially if you are working with a dynamically allocated C string inside this area?

This is a bad idea in general.

Is C line deleted in the catch () file?

And dealing with such things is one of the main reasons. It's not so easy. But I hope you understand that catching an exception and checking ios :: bits are two completely different things. Although you can customize the thread object to throw exceptions instead of just setting the flag bit :)

+2
source

All Articles