C++ - Datei wortweise einlesen und aktuelle Zeile

OP #5477346
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?
Gast #5477411
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...
Gast #5477684
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.
Gast #5477690
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
}
#5477719
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
Gast #5477770
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren