Tout d'abord, faites un ifstream
:
#include <fstream>
std::ifstream infile("thefile.txt");
Les deux méthodes standard sont:
Supposons que chaque ligne se compose de deux nombres et lisez jeton par jeton:
int a, b;
while (infile >> a >> b)
{
// process pair (a,b)
}
Analyse basée sur les lignes, en utilisant des flux de chaînes:
#include <sstream>
#include <string>
std::string line;
while (std::getline(infile, line))
{
std::istringstream iss(line);
int a, b;
if (!(iss >> a >> b)) { break; } // error
// process pair (a,b)
}
Vous ne devez pas mélanger (1) et (2), car l'analyse basée sur les jetons ne gobe pas les nouvelles lignes, vous pouvez donc vous retrouver avec des lignes vides parasites si vous utilisez getline()
après que l'extraction basée sur les jetons vous a conduit à la fin d'un ligne déjà.
int a, b; char c; while ((infile >> a >> c >> b) && (c == ','))
while(getline(f, line)) { }
construction et concernant la gestion des erreurs, veuillez consulter cet (mon) article: gehrcke.de/2011/06/… (Je pense que je n'ai pas besoin d'avoir mauvaise conscience en postant ceci ici, il est même légèrement pré- date cette réponse).Utilisez
ifstream
pour lire les données d'un fichier:Si vous avez vraiment besoin de lire ligne par ligne, procédez comme suit:
Mais il vous suffit probablement d'extraire des paires de coordonnées:
Mise à jour:
Dans votre code que vous utilisez
ofstream myfile;
, cependant leo
dansofstream
signifieoutput
. Si vous souhaitez lire à partir du fichier (entrée), utilisezifstream
. Si vous voulez à la fois lire et écrire, utilisezfstream
.la source
getline
est àstring
voir , alors n'oubliez pas le#include <string>
La lecture d'un fichier ligne par ligne en C ++ peut se faire de différentes manières.
[Rapide] Boucle avec std :: getline ()
L'approche la plus simple consiste à ouvrir un std :: ifstream et une boucle à l'aide d'appels std :: getline (). Le code est propre et facile à comprendre.
[Rapide] Utilisez file_description_source de Boost
Une autre possibilité est d'utiliser la bibliothèque Boost, mais le code devient un peu plus détaillé. Les performances sont assez similaires au code ci-dessus (boucle avec std :: getline ()).
[Le plus rapide] Utilisez le code C
Si les performances sont critiques pour votre logiciel, vous pouvez envisager d'utiliser le langage C. Ce code peut être 4 à 5 fois plus rapide que les versions C ++ ci-dessus, voir référence ci-dessous
Benchmark - Lequel est le plus rapide?
J'ai fait des tests de performances avec le code ci-dessus et les résultats sont intéressants. J'ai testé le code avec des fichiers ASCII contenant 100 000 lignes, 1 000 000 lignes et 10 000 000 lignes de texte. Chaque ligne de texte contient en moyenne 10 mots. Le programme est compilé avec
-O3
optimisation et sa sortie est transmise à/dev/null
afin de supprimer la variable de temps d'enregistrement de la mesure. Enfin, chaque élément de code enregistre chaque ligne avec laprintf()
fonction pour plus de cohérence.Les résultats montrent le temps (en ms) que chaque morceau de code a pris pour lire les fichiers.
La différence de performances entre les deux approches C ++ est minime et ne devrait pas faire de différence dans la pratique. La performance du code C est ce qui rend la référence impressionnante et peut changer la donne en termes de vitesse.
la source
std::cout
vsprintf
.printf()
fonction dans tous les cas par souci de cohérence. J'ai également essayé d'utiliserstd::cout
dans tous les cas et cela n'a fait absolument aucune différence. Comme je viens de le décrire dans le texte, la sortie du programme passe à/dev/null
donc le temps d'impression des lignes n'est pas mesuré.cstdio
. Vous auriez dû essayer de réglerstd::ios_base::sync_with_stdio(false)
. Je suppose que vous auriez obtenu de bien meilleures performances (ce n'est pas garanti car il est défini par l' implémentation lorsque la synchronisation est désactivée).Puisque vos coordonnées appartiennent ensemble par paires, pourquoi ne pas leur écrire une structure?
Ensuite, vous pouvez écrire un opérateur d'extraction surchargé pour les istreams:
Et puis vous pouvez lire un fichier de coordonnées directement dans un vecteur comme celui-ci:
la source
int
jetons depuis le fluxoperator>>
? Comment peut-on le faire fonctionner avec un analyseur de retour arrière (c.-à-d. En cas d'operator>>
échec, restaurer le flux à la position précédente, retourner retour faux ou quelque chose comme ça)?int
jetons, alors leis
flux sera évaluéfalse
et la boucle de lecture se terminera à ce point. Vous pouvez le détecteroperator>>
en vérifiant la valeur de retour des lectures individuelles. Si vous souhaitez restaurer 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 supposez que votre flux d'entrée est en mode de saut d'espaces.Développer la réponse acceptée, si l'entrée est:
vous pourrez toujours appliquer la même logique, comme ceci:
la source
Bien qu'il ne soit pas nécessaire de fermer le fichier manuellement, il est préférable de le faire si la portée de la variable de fichier est plus grande:
la source
Cette réponse est pour Visual Studio 2017 et si vous souhaitez lire à partir d'un fichier texte quel emplacement est relatif à votre application console compilée.
placez d'abord votre fichier texte (test.txt dans ce cas) dans votre dossier de solution. Après la compilation, conservez le fichier texte dans le même dossier avec applicationName.exe
C: \ Users \ "nom d'utilisateur" \ source \ repos \ "solutionName" \ "solutionName"
la source
Il s'agit d'une solution générale pour charger des données dans un programme C ++ et utilise la fonction readline. Cela pourrait être modifié pour les fichiers CSV, mais le délimiteur est un espace ici.
la source