Forum: PC-Programmierung C++ - Datei wortweise einlesen und aktuelle Zeile


von Peter W. (ja_wasser)


Lesenswert?

hallo,
Ich les eine datei mit
1
string wort;
2
while (datei >> wort) {
3
..
4
}

wortweise ein. Nun brauch ich aber die aktuelle zeilenposition. Jemand 
eine idee wie ich das hinkriege? Der >> operator verschlingt ja alle 
unterbrechungszeichen wie ' ' und auch '\n'.

Meine idee wäre, dass ich die gesamte zeile einlese, den zeilenzähler 
hochzähle und die gesamte zeile in einen stringstream wandle und daraus 
wieder wortweise auslese:
1
int zeilennummer = 0;
2
while (getline(datei, zeile) {
3
++zeilennummer;
4
stringstream ss;
5
ss << zeile;
6
while (ss >> wort) { bla }

aber ist vllt nicht sehr elegant und ich hab es auch noch nicht 
ausprobiert. Hat jemand nen anderen vorschlag?

von Carl D. (jcw2)


Lesenswert?

std::getline würde eine Zeile in einen std::string lesen, Zeile 
hochzählen und den String per std::istringstream wie bisher in Worte 
zerlegen.

von Programmiersprachentheaterintendant (Gast)


Lesenswert?

> wieder wortweise auslese:
>
>
1
int zeilennummer = 0;
2
> while (getline(datei, zeile) {
3
> ++zeilennummer;
4
> stringstream ss;
5
> ss << zeile;
6
> while (ss >> wort) { bla }

Das ist aber kein LISP, es fehlen Klammern...

von Rolf M. (rmagnus)


Lesenswert?

Peter W. schrieb:
> ss << zeile;

Ich würde ss.str(zeile) schreiben, es aber ansonsten gleich machen.

von Egon N. (egon2321)


Lesenswert?

https://www.boost.org/doc/libs/1_67_0/libs/spirit/doc/html/index.html

Über welche Dateigrößen sprechen wir denn?

von nfet (Gast)


Lesenswert?

1
#include <iostream>
2
#include <string>
3
#include <sstream>
4
#include <vector>
5
#include <iterator>
6
7
int main()
8
{
9
    std::istringstream datei("test1 test2\n test3 test4");
10
    int zeilennummer = 1;
11
    for (std::string zeile; std::getline(datei, zeile); ++zeilennummer) {
12
        std::istringstream iss(zeile);      
13
        std::vector<std::string> woerter_in_zeile(std::istream_iterator<std::string>{iss}, std::istream_iterator<std::string>());
14
        std::cout << "Zeilennummer " << zeilennummer << " enthaelt " << woerter_in_zeile.size() << " Woerter" << std::endl;
15
    }
16
}

Hier eine Lösung mit Iteratoren.

von nfet (Gast)


Lesenswert?

Vielleicht noch etwas schöner, da die Lebensdauer von Zeilennummer 
gleich noch begrenzt wird und der eigentliche Code zu einem 3 Zeiler 
verkommt:
1
#include <iostream>
2
#include <string>
3
#include <sstream>
4
#include <vector>
5
#include <iterator>
6
7
int main()
8
{
9
    std::istringstream datei("test1 test2\n test3 test4");
10
    for (auto [zeilennummer, zeile] = std::make_pair(1, std::string{}); std::getline(datei, zeile); ++zeilennummer) {
11
        std::istringstream iss(zeile);      
12
        std::vector<std::string> woerter_in_zeile(std::istream_iterator<std::string>{iss}, std::istream_iterator<std::string>());
13
        std::cout << "Zeilennummer " << zeilennummer << " enthaelt " << woerter_in_zeile.size() << " Woerter" << std::endl;
14
    }
15
}

von Keiner N. (nichtgast)


Lesenswert?

nfet schrieb:

> int main()
> {
>     std::istringstream datei("test1 test2\n test3 test4");
>     for (auto [zeilennummer, zeile] = std::make_pair(1, std::string{});
> std::getline(datei, zeile); ++zeilennummer) {
>         std::istringstream iss(zeile);
>         std::vector<std::string>
> woerter_in_zeile(std::istream_iterator<std::string>{iss},
> std::istream_iterator<std::string>());
>         std::cout << "Zeilennummer " << zeilennummer << " enthaelt " <<
> woerter_in_zeile.size() << " Woerter" << std::endl;
>     }
> }

Das ist mal so was von schlecht :)

Mit verlassen der Schleife ist auch dein Vector wieder weg, da im Scope 
deklariert.
Jedes mal den stream neu zu machen sorgt auch für gute Wartezeiten wenn 
die Datei mal etwas größer ist.
Und dann noch eine Ausgabe in der Schleife .... Das ist Murks

von nfet (Gast)


Lesenswert?

Keiner N. schrieb:
> Mit verlassen der Schleife ist auch dein Vector wieder weg, da im Scope
> deklariert.

Das war auch im original so ähnlich. So wie ich das verstanden habe, 
wird im original sogar immer nur das aktuelle Wort benötigt. Dann wäre 
der Vector natürlich tatsächlich schon zu viel des Guten.

Keiner N. schrieb:
> Jedes mal den stream neu zu machen sorgt auch für gute Wartezeiten wenn
> die Datei mal etwas größer ist.

Peter wollte es elegant, nicht schnell ?.

Keiner N. schrieb:
> Und dann noch eine Ausgabe in der Schleife .... Das ist Murks

Naja, statt der Ausgabe hätte ich auch // bla schreiben können.
Man muss mir zugute halten. Meinen Code kann man wenigstens kompilieren.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.