7
votes

Lire un flux de fichiers partiel dans une chaîne à l'aide d'itérateurs

C'est ce que j'ai essayé jusqu'à présent mais sans succès: xxx pré>

Je sais lire le fichier entier. P>

std::string Read( std::ifstream& _file )
{
    std::istreambuf_iterator<char> first( _file );
    std::istreambuf_iterator<char> last();
    return std::string( first, last ); 
}


4 commentaires

Quel est le résultat réel que vous voyez? Aussi, veuillez poster le code réel que vous avez utilisé. Le code ci-dessus ne compile même pas (modifier: avant que Charles ne soit réparé ...).


OK corrigé l'erreur de compilation.Le söser qui était mon mauvais. Tapé de ma tête.


Pas besoin d'utiliser HTML, Markdown fonctionne bien.


Par habitude, j'ai changé Ifstream à Istream dans ma réponse, mais il convient de mentionner explicitement: passez des flux de fichiers comme IStreams ou tstreams (ou, très rarement, iostreams) si vous n'avez pas besoin de méthodes spécifiques à un fichier (ouverte, fermée, etc.).


3 Réponses :


6
votes

Y a-t-il une raison particulière que vous souhaitez utiliser des itérateurs? Vous pouvez simplement lire les octets en un seul Go: xxx pré>

Si vous souhaitez vraiment lire à l'aide d'itérateurs, vous pouvez le faire: P>

std::string ReadPartial( std::ifstream& _file, int _size )
{
    std::istreambuf_iterator<char> first( _file );
    std::istreambuf_iterator<char> last;
    std::string s;
    s.reserve(_size);
    while (_size-- && first != last) s += *first++;
    return s;
}


5 commentaires

Non, ce n'est pas nécéssaire. Mais voudrait savoir si cela est possible. Merci d'avoir répondu


fichier.read (& s [0], taille) n'est pas portable et dangereux. basic_string n'a pas de garantie de stockage contiguë de vecteur.


@Steve: Pour quelle implémentation est-ce vraie?


@Roger: Je préfère tout simplement pas savoir, car la norme permet aux implémentaux de la modifier quand ils le souhaitent. Pourquoi des abstractions si nous allons être encouragés à écrire du code qui suppose une implémentation certaine?


@Steve: stockage contigu est requis pour la chaîne via L'indexation (ce qui manque est une garantie explicite pour les itérateurs). 0x garantit le stockage contigu de toutes les manières pour STD :: String.



5
votes
template<class InIter, class Size, class OutIter>
void copy_n(InIter begin, InIter end, Size n, OutIter dest) {
  for (; begin != end && n > 0; ++begin, --n) {
    *dest++ = *begin;
  }
}

//...
std::string ReadPartial(std::istream& file, int size) {
  std::string result;
  copy_n(istreambuf_iterator<char>(file), istreambuf_iterator<char>(),
         size, back_inserter(result));
  return result;
}

2 commentaires

Mais y a-t-il un moyen de faire quelque chose de similaire à l'aide d'itérateurs ou d'obtenir un itérateur avant d'une ifstream?


@Allen_sm: Bien sûr, vous pouvez utiliser des itérateurs, j'ai déjà inclus copy_n. Vous pouvez écrire un type d'itérateur pour Istreams qui est un itérateur avant (puisque Istreams a une méthode de rechercheg), mais il n'y a pas besoin.



1
votes

Il n'y a pas d'algorithme standard qui peut vous aider ici, mais vous pouvez utiliser celui-ci:

std::string ReadPartial( std::ifstream& _file, int _size )
{
    std::istreambuf_iterator<char> first( _file );
    std::string result;

    copy_n(first, _size, std::back_inserter(result));
    return result; 
}


0 commentaires