Lire le fichier ligne par ligne à l'aide de ifstream en C++
Le contenu de file.txt sont:
5 3
6 4
7 1
10 5
11 6
12 3
12 4
Où 5 3
est une paire de coordonnées.
Comment dois-je traiter ces données ligne par ligne en C++?
Je suis en mesure d'obtenir la première ligne, mais comment puis-je obtenir la ligne suivante du fichier?
ifstream myfile;
myfile.open ("text.txt");
Vous devez vous connecter pour publier un commentaire.
Tout d'abord, faire un
ifstream
:Les deux méthodes standard sont:
Supposons que chaque ligne se compose de deux nombres et de lire jeton par jeton:
Ligne-en fonction de l'analyse, à l'aide de la chaîne de flux:
Vous ne devriez pas mélanger (1) et (2), depuis le jeton en fonction de l'analyse n'est pas engloutir les retours à la ligne, de sorte que vous pouvez vous retrouver avec de fausses lignes vides si vous utilisez
getline()
après la base de jeton d'extraction obtenu vous à la fin d'une ligne déjà.int a, b; char c; while ((infile >> a >> c >> b) && (c == ','))
while(getline(f, line)) { }
construire, et en matière de gestion des erreurs, veuillez jeter un oeil à cette (ma) de l'article: gehrcke.de/2011/06/... (je pense que je n'ai pas besoin d'avoir mauvaise conscience de poster cela ici, elle est même légèrement antérieur à cette réponse).make friends with @KerrekSB
>>
retourne la référence de l'objet de flux de données. La question est donc lorsque le flux atteint eof ce sera retourné qui rend le tout en rupture de boucle.bool
opérateur qui sera de retourfalse
si eof est frappé, et la cause de la boucle à la pause.!fail()
, pasgood()
, qui diffère dans le traitement des expressions du FOLKLORE (voir ici).std::vector<string>
) et ensuite que le récipient après la boucle est terminée. Cela signifie bien sûr que vous devez être en mesure de consommer la totalité du fichier avant de procéder, par exemple, vous ne pouvez pas lire les lignes de manière interactive. (Mais c'est la même chose en Python je pense.) Si la performance est une préoccupation, il pourrait être préférable de lire l'ensemble de la fichier en mémoire en une seule étape, et puis il suffit de stocker l'emplacement des sauts de ligne, par exemple, comme unstd::vector<std::string_view>
, mais je voudrais seulement que si c'est un goulot d'étranglement des performances.Utilisation
ifstream
de lire des données à partir d'un fichier:Si vous avez vraiment besoin de lire ligne par ligne, puis le faire:
Mais vous avez probablement juste besoin d'extraire des paires de coordonnées:
Mise à jour:
Dans votre code que vous utilisez
ofstream myfile;
, cependant lao
dansofstream
signifieoutput
. Si vous voulez lire le fichier (entrée) utilisationifstream
. Si vous voulez à la fois lire et écrire utiliserfstream
.getline
est dansstring
voir, alors n'oubliez pas le#include <string>
Lecture d'un fichier ligne par ligne en C++ peut être fait de différentes façons.
[Rapide] Boucle avec std::getline()
L'approche la plus simple est d'ouvrir un std::ifstream et boucle en utilisant std::getline() appelle. Le code est propre et facile à comprendre.
[Rapide] l'Utilisation de Boost file_description_source
Une autre possibilité est d'utiliser la bibliothèque Boost, mais le code est un peu plus prolixe. La performance est assez similaire au code ci-dessus (en Boucle avec std::getline()).
[Rapide] Utiliser du code C
Si la performance est critique pour votre logiciel, vous pouvez envisager d'utiliser le langage C. Ce code peut être 4 à 5 fois plus rapide que le C++ versions ci-dessus, voir la référence ci-dessous
Point de référence-Lequel est le plus rapide?
J'ai fait quelques tests de performance avec le code ci-dessus et les résultats sont intéressants. J'ai testé le code ASCII des fichiers qui contiennent de 100 000 lignes de, 1 000 000 lignes et 10 000 000 de lignes de texte. Chaque ligne de texte contient 10 mots en moyenne. Le programme est compilé avec
-O3
optimisation et sa sortie est transmis à/dev/null
afin de supprimer les temps d'enregistrement de la variable à partir de la mesure. Dernier, mais pas moins, chaque morceau de code se connecte à chaque ligne avec laprintf()
fonction de la cohérence.Les résultats montrent que le temps (en ms) que chaque morceau de code a fallu pour lire les fichiers.
La différence de performances entre les deux C++ approches est minime et ne devrait pas faire de différence dans la pratique. La performance du code C est ce qui rend l'indice de référence impressionnante et peut être un changeur de jeu en termes de vitesse.
std::cout
vsprintf
.printf()
fonction dans tous les cas, pour des raisons de cohérence. J'ai également essayé d'utiliserstd::cout
dans tous les cas, et de ce fait absolument aucune différence. Comme je l'ai décrit dans le texte, la sortie du programme va à/dev/null
de sorte que le temps pour imprimer les lignes n'est pas mesurée.Depuis vos coordonnées en tant quentité paires, pourquoi ne pas écrire un struct pour eux?
Ensuite, vous pouvez écrire une surcharge de l'extraction de l'opérateur pour istreams:
Et puis vous pouvez lire un fichier de coordonnées directement dans un vecteur comme ceci:
int
jetons à partir du flux dansoperator>>
? Comment peut-on le faire fonctionner avec un retour en arrière de l'analyseur (c'est à dire quandoperator>>
échoue, faire reculer le ruisseau à la position précédente déclaration de fin de falsification ou quelque chose comme ça)?int
jetons, puis leis
flux d'évaluer àfalse
et la lecture en boucle prendra fin à ce moment. Vous pouvez détecter cette dansoperator>>
en vérifiant la valeur de retour de la personne lit. Si vous voulez retourner dans le flux, vous appelezis.clear()
.operator>>
il est plus correct de direis >> std::ws >> coordinates.x >> std::ws >> coordinates.y >> std::ws;
car sinon vous êtes en supposant que votre flux d'entrée est dans l'espace-saut de mode.Expansion sur la accepté de répondre, si l'entrée est:
vous serez toujours en mesure d'appliquer la même logique, comme ceci:
Cette réponse est pour visual studio 2017 et si vous voulez lire depuis un fichier texte dont la localisation est par rapport à votre compilé application console.
d'abord mettre votre fichier texte (test.txt dans ce cas-ci) dans votre dossier de solution. Après la compilation de garder le fichier texte dans le même dossier avec applicationName.exe
C:\Users\"nom d'utilisateur"\source\repos\"solutionName"\"solutionName"
C'est une solution générale pour le chargement de données dans un programme en C++ et utilise la fonction readline. Ce pourrait être modifié pour les fichiers CSV, mais le délimiteur est un espace ici.
Bien qu'il n'est pas nécessaire de fermer le fichier manuellement, mais c'est une bonne idée de le faire si la portée de la variable fichier est plus grand: