8
votes

Comment puis-je lire de la mémoire comme à partir d'un fichier utilisant iostream?

J'ai un fichier texte simple chargé dans la mémoire. Je veux lire de la mémoire comme je voudrais lire à partir d'un disque comme ici: xxx

mais j'ai un fichier en mémoire. J'ai une adresse en mémoire et une taille de ce fichier.

Ce que je dois faire pour avoir la même fluidité que de traiter avec le fichier dans le code ci-dessus?


6 Réponses :


6
votes

Vous pouvez utiliser iSTringingStream pour cela. XXX


4 commentaires

Voulez-vous dire (i) Stringstream?


IIRC Istrstream a été obsolète.


Cela nécessite que les données soient copiées de la chaîne, dans le tampon de StringStream. La solution de boost suggère donc que @ybungalobill va être plus rapide, mais cette solution fonctionnera, et cela ne dépend pas des bibliothèques externes.


Votre idée est fondamentalement la même chose que NIM. Mais ce VÉIANT crée en fait une copie des données de texte dans le fichier . Ainsi, si le texte est énorme (comme le contenu d'un fichier, cela peut être un problème).



5
votes

6 commentaires

Fonctionnalité déjà prise en charge par la STL, donc pas besoin d'utiliser Boost.


Martin, pouvez-vous expliquer votre mode d'utilisation d'un tableau comme Streambuf en plus de copier à Stringstream?


@Martin: STL n'a rien pour cela, sans effectuer une copie des données. La solution de NIM avait l'air agréable, mais malheureusement en train de regarder la norme, je vois que c'est au plus de "mise en œuvre définie".


PubsetBuf (appelé par SETBUF) Il s'agit d'une fonction de membre virtuel qui doit être redéfinie dans des classes dérivées pour se comporter comme prévu en définissant la matrice de n caractères pointés par S comme nouveau tampon de caractères. < / Devis> L'accent est ajouté. Donc, oui, c'est la mise en œuvre de la manière dont cela fonctionne, mais cela devrait fonctionner comme prévu.


@Martin: Sa carte mémoire tampon, elle devrait être utilisée pour la mise en mémoire tampon pour la lecture et l'écriture de fichiers, des sockets, du clavier, de l'écran, etc. Il n'est pas prévu d'être utilisé comme source de données . La norme ne dit pas que l'un des flux devrait conserver les données qui y étaient initialement.


@ybungalobillill: Vous devez lire ce que la documentation sur le tampon de flux dit avec un peu plus de soin. L'utilisation ci-dessus est parfaitement valide.



12
votes

Vous pouvez faire quelque chose comme les suivants .. xxx

puis utilisez-le dans votre getline appels ...

Remarque: getline ne comprend pas la différence DOS / UNIX, de sorte que le \ r est inclus dans le texte, c'est pourquoi je le chombis! xxx


6 commentaires

C'est ce que je cherche! Où mettre cette adresse et cette adresse dans istringstream . Mais cela ne fonctionne pas avec getline ... J'ai vérifié ce tampon et sa gamme de caractères et de nouvelles lignes est "\ r \ n" style windows. Donc, le tampon est ok. Je ne sais pas quoi faire pour obtenir ces lignes.


Un problème avec ce code: il n'est pas garanti de travailler. L'effet de pubsetbuf sur basic_streambuf est "défini par la mise en œuvre". Il s'attend également à un pointeur non-Const, il peut donc modifier les données pointues sur Portback .


@ybungalobillill: mal, correct et correct sur les deux points. Mais toujours non pertinent. PubsetBuf (appelé par SETBUF) Il s'agit d'une fonction de membre virtuel qui doit être redéfinie dans des classes dérivées pour se comporter comme prévu en définissant la matrice de n caractères pointés par S comme nouveau tampon de caractères. < / Devis> L'accent est ajouté. Donc, oui, c'est la mise en œuvre de la manière dont il fonctionne (mais la mise en œuvre définie ne signifie pas qu'il ne fonctionnera pas), il devrait fonctionner comme prévu . Alors, que se passe-t-il si le putback modifie le tampon! Nous passons une matrice modifiable en tant que ce qui ne devrait pas être un problème.


@Martin: C'est le caractère tampon , il devrait être utilisé pour la mise en mémoire tampon de lecture et de rédaction de fichiers, de sockets, de claviers, d'écran, etc., il n'est pas attendu être utilisé comme source de données. La norme ne dit pas que l'un des flux devrait conserver les données qui y étaient initialement.


Merci pour de grandes réponses! En fait, le code ci-dessus ne fonctionne pas. Je l'ai testé avec simple \ n pas '\ r \ n'. Il fonctionne lors de la compilation avec GCC sur Linux mais pas dans Visual Studio 2010 . Depuis que je dois écrire sur Windows (écrire, c'est-à-dire add-on), cela ne me convient pas. Je pense que l'utilisation de Boost n'est pas une option. Je n'aime pas ajouter d'autres bibliothèques pour cette tâche "simple". Le fichier est assez gros (257 Ko), donc je préférerais ne pas le copier à la chaîne, puis transmettez-le à Istringstream .


@ Cichyk24: ce n'est pas censé fonctionner. Ce n'est pas garanti par la norme. Voir Stackoverflow.com/Questtions/4349778/... Pour plus de détails. Donc, la meilleure chose à faire si vous ne voulez pas copier et veulent l'utiliser comme source d'un flux, est d'utiliser Boost.



1
votes

Utilisez

std::stringstream


0 commentaires

1
votes

Voici comment je le ferais:

#include <sstream>

std::istringstream stream("some textual value");
std::string line;
while (std::getline(stream, line)) {
    // do something with line
}


0 commentaires

3
votes

J'ai trouvé une solution qui fonctionne sur VC ++ depuis NIM solution fonctionne uniquement sur le compilateur GCC (grand merci, cependant. Grâce à votre réponse, j'ai trouvé d'autres réponses qui m'a aidé!

Il semble que d'autres personnes ont problème similaire aussi. J'ai fait exactement comme ici et ici . p>

pour lire à partir d'un morceau de mémoire, comme formez un iStream, vous devez le faire: p> xxx pré>

edit: strong> et si Vous avez "\ r \ n 'nouvelles lignes faire comme NIM a écrit: p>

if (*line.rbegin() == '\r') line.erase(line.end() - 1);


1 commentaires

J'écris, c'est-à-dire un complément et une efficacité, il est crucial de sorte qu'il ne ressort donc pas une fenêtre qui suggère de le désactiver car il est lent. Si j'écrivais une application «normale» bien sûr, cela ne me dérangerait pas de bibliothèques externes :)