Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » zeilen zählen

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 < [ 2 ]
000
14.09.2004, 15:59 Uhr
CaesarCortezz
minderer Student


Hi Leutz,
wieso funzt folgendes Program nicht?


C++:
int zeilen_zaehlen(std::string datei) {
    int zeilen;
    std::ifstream inf(datei.c_str());
    while (!inf.eof()) {
        zeilen = zeilen + 1;
    }
    std::cout << zeilen << std::endl;
    inf.close();
    return 0;
}



PS: er gibt mir dann hundertachtzigtausendirgendwas aus...
gibt es ein std::int????
--
Thus spake the master programmer:

``When the program is being tested, it is too late to make design changes.''
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
14.09.2004, 16:07 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)


probier mal so...
ungetestet

C++:
int zeilen_zaehlen(std::string datei) {
    int zeilen;
    std::string temp;
    std::ifstream inf(datei.c_str());
    for(zeilen=0;std::getline(inf,temp);++zeilen);
    inf.close();
    return zeilen;
}

int main(){std::cout<<zeilen_zaehlen("test.txt");}


--
...fleißig wie zwei Weißbrote
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
14.09.2004, 16:16 Uhr
Tommix



Hallo,
der eigentliche Fehler ist, daß Du zeilen nicht initialisierst und daher von vornherein ein undefinierter Wert hochgezählt wird. Muß also heißen:

C++:
int zeilen = 0;


Zur zweite Frage: int ist ein eingebauter Datentyp und daher in keinem namespace.

Gruß, Tommix
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
14.09.2004, 17:11 Uhr
virtual
Sexiest Bit alive
(Operator)


Warum das Rand zweimal erfinden?

C++:
#include <fstream>
#include <iostream>
#include <iterator>
#include <algorithm>

int main()
{
        const char* datei_name = "lc.cpp";
        std::ifstream in(datei_name);
        in.unsetf(std::ios_base::skipws);
        int count = std::count(std::istream_iterator<char>(in), std::istream_iterator<char>(),'\n');
        std::cout<<datei_name<<" hat "<<count<<" Zeilen."<<std::endl;
}


--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
14.09.2004, 17:16 Uhr
(un)wissender
Niveauwart


Ah, endlich jemand der const vor seine char* Pointer schreibt.
Es fehlt, glaube ich, noch #include <iomanip> für flags.
--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
14.09.2004, 17:27 Uhr
virtual
Sexiest Bit alive
(Operator)


@(un)wissender:
istream ist von basic_ios abgelitten und und das wiederum von ios_base. Die Konstanten stammen somit aus einer Basisklasse. Eine ableitiung kann man nur dann machen, wenn die Basisklasse komplett bekannt ist, folglich muß das ios_base implizit durch das Include <iostream> bekannt sein.
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
14.09.2004, 17:28 Uhr
(un)wissender
Niveauwart


Gut, bin überzeugt.
--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
14.09.2004, 18:25 Uhr
CaesarCortezz
minderer Student


Danke Leute
so viele Lösungen (zu viele optionen zu viele optionen)
--
Thus spake the master programmer:

``When the program is being tested, it is too late to make design changes.''
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
15.09.2004, 14:10 Uhr
CaesarCortezz
minderer Student


@virtual
Nur noch ne kleine (eigentlich große) Frage


C++:
const char* datei_name = "lc.cpp";
        std::ifstream in(datei_name);
        in.unsetf(std::ios_base::skipws);
        int count = std::count(std::istream_iterator<char>(in), std::istream_iterator<char>(),'\n');
        std::cout<<datei_name<<" hat "<<count<<" Zeilen."<<std::endl;




Ich seh überhaupt net durch könntest du mir das erklären.
Wäre sehr freundlich, danke.
Caesar
--
Thus spake the master programmer:

``When the program is being tested, it is too late to make design changes.''
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
15.09.2004, 14:55 Uhr
virtual
Sexiest Bit alive
(Operator)



Zitat von CaesarCortezz:
@virtual
Nur noch ne kleine (eigentlich große) Frage


C++:
const char* datei_name = "lc.cpp";
        std::ifstream in(datei_name);
        in.unsetf(std::ios_base::skipws);
        int count = std::count(std::istream_iterator<char>(in), std::istream_iterator<char>(),'\n');
        std::cout<<datei_name<<" hat "<<count<<" Zeilen."<<std::endl;




Ich seh überhaupt net durch könntest du mir das erklären.
Wäre sehr freundlich, danke.
Caesar


Nun gut:

C++:
const char* datei_name = "lc.cpp";


Dürfte klar sein, ich möchte nur an einer Stelle den Dateinamen ändern, deshalb mach ich eine entsprechende Variable.


C++:
        std::ifstream in(datei_name);


Erzeuge einen EingabeStream, öffnet diesen gleich. Übrigens is kein explizites in.close() nachher erforderlich, weil das automatisch durch den Destructor gemacht wird, wenn die Funktion verlassen wird.


C++:
        in.unsetf(std::ios_base::skipws);


Standardmäßig sind input streams so eingestellt, daß sie einfach die Zeichen überspringen, die als Whitespaces gelten. Neben dem Space als solchen gilt auch das newline als Space. Genau an diesem Zeichen sind wir aber interessiert, deshalb lösche ich dieses Flag im Stream, welches die Whitespaces überspringt.


C++:
        int count = std::count(std::istream_iterator<char>(in), std::istream_iterator<char>(),'\n');



Ich denke mal, das interessiert dich am meisten. Fangen wir mal mit dem count an:
Im besser zu begreifen, was es genau macht, nehmen wir mal diesen Code hier:

C++:
int zahlen[] = { 1, 2, 2, 5, 9 };
int c = std::count(&zahlen[0], &zahlen[5], 2);


Das count soll einen bereich nach einem bestimmten Wert durchsuchen und die Anzahl der Vorkommnisse zurückgeben. Die ersten beiden parameter geben an, was der Bereich ist (Nennen wir es mal für ein paar Momente "Bereichsgrenzen") und der letzte gibt den gesuchten Wert an. Wir suchen also im einem wie auch immer definierten Bereich den Wert 2.
Spannend ist die Sache mit den Bereichsgrenzen: Im obigen Beispiel ist die untere Bereichgrenze &zahlen[0], also der Zeiger auf das erste Element im Array zahlen; die obere grenze zeigt auf das erste Element, welches uns nicht mehr interessiert. (Der Zeiger &zahlen[5] zeigt also sozusagen auf das 6te Element in zahlen, allerdings is das ja garnicht da).

Code:
count(anfang, ende, wert)


Durchsucht also alle Werte beginnend an Stelle anfang bis (aber ohne!) ende nach wert.

In C++ wird sehr viel Iteratoren gearbeitet. Vereinfacht sind Iteratoren objekte, die sich sehr ähnlich wie Zeiger benehmen können. Minimal gesehen, muß ein Iterator folgende Operationen bereitstellen:

Code:
*i : Deferenzieren, dh den Inhalt preisgeben, wo der Iterator hinzeigt
++i und i++: Auf das nächste Element zeigen
i==j: Prüfen, ob die Iteratoren gleich sind.


Weitere Operationen können auch Unterstützt werden, das hängt von dem konkreten Iterator ab. Ein Iterator is also ein Stinknormaler Zeiger, oder eben eine Klasse, die bestimmte Operatoren überladen hat, mindestens die von oben, manchmal weitere. Ist ein weites feld, belassen wir es erstmal dabei.
Um zum count zurückzukommen: die Bereichsgrenzen werden also mit Iteratoren markiert.
In dem ursprünglichen Beispiel wurde eben kein zeiger, sondern ein Iterator verwendet. der istream_iterator<char> stellt die og Funktionen etwa so bereit:

Code:
*i : Das aktuelle Zeichen der Ausgabedatei zurückgeben
++i und i++: Das nächste zeichen aus der Ausgabe datei lesen.


std::istream_iterator<char>(in) Ist also ein iterator für das erste noch nicht gelesene ZEichen im Stream
std::istream_iterator<char>() Ist also ein iterator für EOF, also dem nicht existenten zeichen nach dem letzten Zeichen im Stream.

Leider ist die ganze Sache recht komplex, deshalb wirst du ggf. nicht alles verstanden haben, aber ich nehme mal an, ein wenig mehr dunkel ins licht gebracht zu haben
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ]     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: