
Herzogin
Der Inhalt von file.txt ist:
5 3
6 4
7 1
10 5
11 6
12 3
12 4
Woher 5 3
ist ein Koordinatenpaar. Wie verarbeite ich diese Daten Zeile für Zeile in C++?
Ich kann die erste Zeile abrufen, aber wie erhalte ich die nächste Zeile der Datei?
ifstream myfile;
myfile.open ("file.txt");

Kerrek SB
Machen Sie zuerst eine ifstream
:
#include <fstream>
std::ifstream infile("thefile.txt");
Die zwei Standardmethoden sind:
-
Nehmen Sie an, dass jede Zeile aus zwei Zahlen besteht und lesen Sie Token für Token:
int a, b;
while (infile >> a >> b)
{
// process pair (a,b)
}
-
Zeilenbasiertes Parsing mit String-Streams:
#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)
}
Sie sollten (1) und (2) nicht mischen, da das tokenbasierte Parsing keine Zeilenumbrüche verschlingt, sodass Sie bei Verwendung möglicherweise mit falschen Leerzeilen enden getline()
Nach der tokenbasierten Extraktion sind Sie bereits am Ende einer Zeile.

K-ballo
Verwenden ifstream
Daten aus einer Datei lesen:
std::ifstream input( "filename.ext" );
Wenn Sie wirklich Zeile für Zeile lesen müssen, dann tun Sie dies:
for( std::string line; getline( input, line ); )
{
...for each line in input...
}
Aber Sie müssen wahrscheinlich nur Koordinatenpaare extrahieren:
int x, y;
input >> x >> y;
Aktualisieren:
In Ihrem Code verwenden Sie ofstream myfile;
jedoch die o
in ofstream
steht für output
. Wenn Sie aus der Datei lesen möchten (Eingabe), verwenden Sie ifstream
. Wenn Sie sowohl lesen als auch schreiben möchten, verwenden Sie fstream
.

Hugo Teixeira
Das Lesen einer Datei Zeile für Zeile in C++ kann auf verschiedene Arten erfolgen.
[Fast] Schleife mit std::getline()
Der einfachste Ansatz besteht darin, einen std::ifstream zu öffnen und eine Schleife mit std::getline() -Aufrufen auszuführen. Der Code ist sauber und leicht verständlich.
#include <fstream>
std::ifstream file(FILENAME);
if (file.is_open()) {
std::string line;
while (std::getline(file, line)) {
// using printf() in all tests for consistency
printf("%s", line.c_str());
}
file.close();
}
[Fast] Verwenden Sie file_description_source von Boost
Eine andere Möglichkeit besteht darin, die Boost-Bibliothek zu verwenden, aber der Code wird etwas ausführlicher. Die Leistung ist dem obigen Code ziemlich ähnlich (Schleife mit std::getline()).
#include <boost/iostreams/device/file_descriptor.hpp>
#include <boost/iostreams/stream.hpp>
#include <fcntl.h>
namespace io = boost::iostreams;
void readLineByLineBoost() {
int fdr = open(FILENAME, O_RDONLY);
if (fdr >= 0) {
io::file_descriptor_source fdDevice(fdr, io::file_descriptor_flags::close_handle);
io::stream <io::file_descriptor_source> in(fdDevice);
if (fdDevice.is_open()) {
std::string line;
while (std::getline(in, line)) {
// using printf() in all tests for consistency
printf("%s", line.c_str());
}
fdDevice.close();
}
}
}
[Fastest] Verwenden Sie C-Code
Wenn die Leistung Ihrer Software entscheidend ist, können Sie die Verwendung der Sprache C in Erwägung ziehen. Dieser Code kann 4-5 Mal schneller sein als die C++-Versionen oben, siehe Benchmark unten
FILE* fp = fopen(FILENAME, "r");
if (fp == NULL)
exit(EXIT_FAILURE);
char* line = NULL;
size_t len = 0;
while ((getline(&line, &len, fp)) != -1) {
// using printf() in all tests for consistency
printf("%s", line);
}
fclose(fp);
if (line)
free(line);
Benchmark – Wer ist schneller?
Ich habe einige Leistungsbenchmarks mit dem obigen Code durchgeführt und die Ergebnisse sind interessant. Ich habe den Code mit ASCII-Dateien getestet, die 100.000 Zeilen, 1.000.000 Zeilen und 10.000.000 Zeilen Text enthalten. Jede Textzeile enthält durchschnittlich 10 Wörter. Das Programm wird mit kompiliert -O3
Optimierung und deren Ausgabe weitergeleitet wird /dev/null
um die Aufzeichnungszeitvariable aus der Messung zu entfernen. Zu guter Letzt protokolliert jedes Stück Code jede Zeile mit der printf()
Funktion für Konsistenz.
Die Ergebnisse zeigen die Zeit (in ms), die jeder Codeabschnitt benötigte, um die Dateien zu lesen.
Der Leistungsunterschied zwischen den beiden C++-Ansätzen ist minimal und sollte in der Praxis keinen Unterschied machen. Die Leistung des C-Codes macht den Benchmark beeindruckend und kann in Bezug auf die Geschwindigkeit ein Spielveränderer sein.
10K lines 100K lines 1000K lines
Loop with std::getline() 105ms 894ms 9773ms
Boost code 106ms 968ms 9561ms
C code 23ms 243ms 2397ms

Da Ihre Koordinaten als Paare zusammengehören, warum schreiben Sie nicht eine Struktur für sie?
struct CoordinatePair
{
int x;
int y;
};
Dann können Sie einen überladenen Extraktionsoperator für istreams schreiben:
std::istream& operator>>(std::istream& is, CoordinatePair& coordinates)
{
is >> coordinates.x >> coordinates.y;
return is;
}
Und dann können Sie eine Datei mit Koordinaten direkt in einen Vektor wie diesen einlesen:
#include <fstream>
#include <iterator>
#include <vector>
int main()
{
char filename[] = "coordinates.txt";
std::vector<CoordinatePair> v;
std::ifstream ifs(filename);
if (ifs) {
std::copy(std::istream_iterator<CoordinatePair>(ifs),
std::istream_iterator<CoordinatePair>(),
std::back_inserter(v));
}
else {
std::cerr << "Couldn't open " << filename << " for reading\n";
}
// Now you can work with the contents of v
}

Gsamaras
Erweiterung der akzeptierten Antwort, wenn die Eingabe lautet:
1,NYC
2,ABQ
...
Sie können immer noch dieselbe Logik anwenden, wie folgt:
#include <fstream>
std::ifstream infile("thefile.txt");
if (infile.is_open()) {
int number;
std::string str;
char c;
while (infile >> number >> c >> str && c == ',')
std::cout << number << " " << str << "\n";
}
infile.close();

Universum
Diese Antwort gilt für Visual Studio 2017 und wenn Sie aus einer Textdatei lesen möchten, welcher Speicherort relativ zu Ihrer kompilierten Konsolenanwendung ist.
Legen Sie zuerst Ihre Textdatei (in diesem Fall test.txt) in Ihren Lösungsordner. Belassen Sie die Textdatei nach dem Kompilieren im selben Ordner wie applicationName.exe
C:\Benutzer\”Benutzername”\Quelle\Repos\”Lösungsname”\”Lösungsname”
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ifstream inFile;
// open the file stream
inFile.open(".\\test.txt");
// check if opening a file failed
if (inFile.fail()) {
cerr << "Error opeing a file" << endl;
inFile.close();
exit(1);
}
string line;
while (getline(inFile, line))
{
cout << line << endl;
}
// close the file stream
inFile.close();
}

Vijay Bansal
Es besteht zwar keine Notwendigkeit, die Datei manuell zu schließen, aber es ist eine gute Idee, dies zu tun, wenn der Gültigkeitsbereich der Dateivariablen größer ist:
ifstream infile(szFilePath);
for (string line = ""; getline(infile, line); )
{
//do something with the line
}
if(infile.is_open())
infile.close();
10032800cookie-checkLesen Sie die Datei Zeile für Zeile mit ifstream in C++yes