1
class WavFile
{
    std::vector<short> SoundData;

public:

    std::vector<short> getSoundData()
    {
        return SoundData;
    }
}

Normally I'd use fread( &SoundData[0], 1, 1337, SomeFile );

But now that I'm using a vector inside a class, I'm having trouble with the following:

  • Knowing how to set the vector size outside the class.

  • And I'm not sure how to use the method as an argument for fread to put the data inside the vector.

Tek
  • 2,888
  • 5
  • 45
  • 73
  • I'm don't know why you need to resize the vector outside of the class, but for reading the file into your vector, you can use `std::istream_iterator` coupled to `std::copy` (found in headers iostream / algorithm) – Jean-Marie Comets Dec 01 '12 at 13:43
  • @Jean-MarieComets Because if I don't fread() won't write into the vector. I'm a newbie so I haven't looked into the istream_iterator method. Care to show a sample of what that'd look like? – Tek Dec 01 '12 at 13:50
  • Check out [this](http://ubuntuforums.org/showthread.php?t=67867) page for more information. – Jean-Marie Comets Dec 01 '12 at 14:55
  • @Jean-MarieComets http://stackoverflow.com/questions/13665534/getting-desired-binary-data-ranges-from-stdistreambuf-iterator-and-stdifstre This is why I don't use std::istream_iterator btw. – Tek Dec 02 '12 at 02:08
  • @Jean-MarieComets Since I can't use `std::copy` for the above reason. I have to use `fstream::read`, which means I have to set the size of the vector outside of the class before I can use it. – Tek Dec 02 '12 at 07:40

3 Answers3

2

What you are trying to do is bad in general. There are some main points to it:

If you are encapsulating vector in class, you can still operate on it normally from the outside if it's public.

WavFile WF;
void* Ptr = WF.SoundData.data();
// void* Ptr = &WF.SoundData[0]; - C++03

You can also wrap some of the calls to the vector, .resize() for example:

void WavFile::resize(vector::size_type new_size) {
    SoundData.resize(new_size);
}

void* WavFile::getRawPtr () {
    return SoundData.data();
    // return (&SoundData[0]); - C++03
}

If you are using std::vector, you should also use corresponding C++ read functions on it. Treating vector as a memory array is valid, but there are better ways to use it, fstream for example.

If you are encapsulating vector (or any std container in general), don't return it by value! It will cause all of the elements to be copied. Instead, return a const-reference to container, or, even better, range.

Bartek Banachewicz
  • 38,596
  • 7
  • 91
  • 135
  • Well first, thank you so much. I knew of resize it just never hit me to use it (newbie woes). Still, would probably have not figured out to use it as an argument to a method. As for the last points, fread only accepts pointer as an argument so I wasn't going to return the value in the end it was just an example. – Tek Dec 01 '12 at 13:45
  • One small question, is it ok to return it by value if I don't want to implement a wrapper when I want to do something like `WF.getSoundDataVector().size()`? – Tek Dec 01 '12 at 13:47
  • No, since still all of the elements will be copied to a temporary, and then the `.size()` will be called. Returning by reference is just adding `const&` to return type, nothing else! And if you want to check which functions are accessible by const object, you can look in lang. reference. Anyway, as I said, you should probably return `range` for reading, it's more general (i.e. you can change inner container without affecting code that's using your class). – Bartek Banachewicz Dec 01 '12 at 16:15
  • And just one more thing, @Tek. Don't use `short` type, unless you are perfectly sure you need 16-bit type (using other library, perhaps). And if you need to use it that way, mark it explicitly by `typedef short int16;` or `using int16 = short;`. `short` size isn't constant, and it's not sensible to use it for arithmetics. – Bartek Banachewicz Dec 01 '12 at 16:19
1
  • Knowing how to set the vector size outside the class.

You can construct the vector passing the size to the vector's constructor.

  • And I'm not sure how to use the method as an argument for fread to put the data inside the vector.

Why are you using fread to begin with? Why not fstream?

Also, once you initialize the vector passing the size, you can use &v[0] just as you would use if it was declared as c-array (i.e float v[const_size]).

Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • http://stackoverflow.com/questions/13665534/getting-desired-binary-data-ranges-from-stdistreambuf-iterator-and-stdifstre This is why I don't use fstream. – Tek Dec 02 '12 at 02:08
0

You cannot use vector as argument to fread. You have to allocate a block of memory (short buffer[SIZE]) as buffer to read data in, then insert data element by element to vector from the buffer.

Although fread is allowed in C++, it's better to use native C++ way to read file, such as fstream.

TieDad
  • 9,143
  • 5
  • 32
  • 58
  • Since everyone suggested `fstream`, this is why I didn't use it: http://stackoverflow.com/questions/13665534/getting-desired-binary-data-ranges-from-stdistreambuf-iterator-and-stdifstre – Tek Dec 02 '12 at 02:09