J'ai besoin d'obtenir tout le contenu d'un flux, sans vraiment les extraire (tout comme stringstream::str()
). J'ai essayé basic_stringbuf::str()
, mais il se comporte incorrectement lorsque le flux est vide. Pour éviter ce cas, j'ai essayé le basic_stringbuf::in_avail()
, mais cela n'a pas très bien marché non plus.Quelle est la fiabilité de basic_stringbuf :: in_avail() et basic_stringbuf :: str()?
Dans le cas de test suivant, in_avail()
ne retourne pas le nombre d'éléments disponibles sur le flux, et str()
retours plus éléments que ce qui est actuellement là-bas:
#include <iostream>
#include <iterator>
#include <vector>
#include <sstream>
// extracts everything from the stream
std::vector<unsigned char> stream2vector(std::basic_istream<unsigned char>& stream)
{
std::vector<unsigned char> retreivedData;
std::istreambuf_iterator<unsigned char> it(stream);
const std::istreambuf_iterator<unsigned char> endOfStream;
retreivedData.insert(retreivedData.begin(), it, endOfStream);
return retreivedData;
}
int main() {
std::basic_stringbuf<unsigned char> buf;
std::basic_iostream<unsigned char> stream(&buf);
unsigned char array[5] = { 1, 2, 3, 4, 5 };
stream.write(array, 5);
std::cout << "rdbuf()->in_avail(): " << buf.in_avail() << "\n";
std::vector<unsigned char> d1 = stream2vector(stream);
std::cout << "d1.size(): " << d1.size() << "\n";
std::cout << "\n";
// d2 should be empty
std::vector<unsigned char> d2 = stream2vector(stream);
std::cout << "d2.size(): " << d2.size() << "\n";
std::basic_string<unsigned char> s = buf.str();
std::cout << "buf.str().size(): " << buf.str().size() << "\n";
}
Compiler sur g ++ 4.4, le la sortie est:
rdbuf()->in_avail(): 1 // expected: 5
d1.size(): 5 // as expected
d2.size(): 0 // as expected
buf.str().size(): 5 // expected: 0
Qu'est-ce que je fais mal? Quelle est la meilleure façon de faire ce que j'essaye?
Merci beaucoup.
Merci pour les commentaires. Ce que j'essaie de faire est de lire tout le contenu du flux sans les extraire, ce que fait actuellement 'stream2vector'. De cette façon, je peux appeler 'stream2vector' à plusieurs reprises sur un flux donné (comme le montre l'exemple, cela n'est pas possible avec cette implémentation basée sur l'itérateur). –
Ou, pour le dire autrement, j'essaie d'écrire 'std :: vector stream2vector (const std :: basic_istream & stream)'. –
@Pedro: Ok, alors sauvegardez simplement la position du pointeur get (avec 'tellg'), puis utilisez' seekg' lorsque vous avez fini de repositionner le pointeur get. –