C++ Werte bestimmen



  • Hay!

    Ich möchte in C++ aus einer Textdatei Werte einlesen und anschließend will ich bestimmen ob dieser Wert ein int oder ein string ist 😕

    also bis jetzt siehts so aus:

    fstream file;
    string line;
    file.open("text.txt");
    if(file.is_open()){
    while(!file.eof()){
    file >> line;
    // So und hier muss halt überprüft werden ob line ein int ist oder ein string
    }
    }

    Jedoch weiß ich nicht wie ich das machen soll... sollte ich es überhaupt in string line addieren? mit einem array wär das ganze noch praktischer aber ich weiß nicht welchen Datentyp dieser dann annehmen soll 🙄

    Würde mich über nicht allzu komplizierte Antworten freuen 👍



  • Hi,

    zeig mal den Aufbau deiner Textdatei.
    Du hast einen Logikfehler drin. Du musst 1. Lesen, 2. Prüfen ob Lesen erfolgreich war, 3. Eingelesene verarbeiten, falls erfolgreich.


  • Mod

    Etwas ist ein int, wenn es als int gelesen werden kann. Lies also ints und wenn es nicht funktioniert, lies es stattdessen als string. Und kauf dir ein neues C++-Buch. Wer while(!eof) kann kein guter Lehrer sein.



  • in der Textdatei steht z.B

    4

    hallo

    3

    2
    1

    bye
    2

    und dann will ich jedes int und jeden string trennen



  • Joa, also so, wie es SeppJ gesagt hat. Schritt 1 und 2 geht in einem Rutsch

    file >> variable



  • SeppJ schrieb:

    Etwas ist ein int, wenn es als int gelesen werden kann. Lies also ints und wenn es nicht funktioniert, lies es stattdessen als string. Und kauf dir ein neues C++-Buch. Wer while(!eof) kann kein guter Lehrer sein.

    Ja aber wie kann ich nur ints lesen? es liest ja automatisch auch die strings mit? "wenn es nicht funktioniert, lies es stattdessen als string" Ich kann aber nicht den DatenTypen von der line überprüfen weil dass ja direkt diesen Wert annimmt oder wie sollte dass gehn 😕

    und was ist an !eof() so schlimm? 😮 sagt ja nur solange es nich am ende ist mach das folgende...


  • Mod

    seb1234 schrieb:

    und was ist an !eof() so schlimm? 😮 sagt ja nur solange es nich am ende ist mach das folgende...

    Nein, sagt es nicht. Es sagt, "so lange das letzte mal nicht das Ende erreicht wurde". Also total falsche Logik, wie out schon erklärt hat.

    Ja aber wie kann ich nur ints lesen? es liest ja automatisch auch die strings mit?

    Was passiert denn, wenn du "Hallo" in einen int liest? Steht dann etwa "Hallo" im int?



  • SeppJ schrieb:

    seb1234 schrieb:

    und was ist an !eof() so schlimm? 😮 sagt ja nur solange es nich am ende ist mach das folgende...

    Nein, sagt es nicht. Es sagt, "so lange das letzte mal nicht das Ende erreicht wurde". Also total falsche Logik, wie out schon erklärt hat.

    Ja aber wie kann ich nur ints lesen? es liest ja automatisch auch die strings mit?

    Was passiert denn, wenn du "Hallo" in einen int liest? Steht dann etwa "Hallo" im int?

    ähm nein "Hallo" steht dann nicht im int. Es kommt halt einfach gar nichts. Also das Programm beendet nicht.



  • Ich geb dir mal eine einfache Lösung. Du versuchst nun alles zu kommentieren, und postest dann deine Kommentare dazu. Wenn du etwas nicht kennst/verstehst, fragst du mal google.

    #include <iostream>
    #include <fstream>
    #include <string>
    using namespace std;
    
    int main()
    {
    	int zahl;
    	string str;
    
    	for (ifstream file("test.txt");;)
    	{
    		if (file >> zahl)
    			cout << zahl << '\n';
    		else if(file.fail())
    		{
    			file.clear();
    			if (file >> str)
    				cout << str << '\n';
    		}
    		else if (file.eof())
    			break;
    	}
    
    }
    


  • Meine nicht unbedingt effiziente, aber schnell geschriebene Standardlösung wäre, getline zu verwenden und dann einfach in einer for-loop mit isdigit testen es nur eine Zahl ist (bzw. vorne noch +- zulassen bei Länge >= 2).

    Es kommen bei mir nämlich die Frage auf: Was ist mit " 42" (mit Space) - ist das ein Int oder ein String? Und was ist mit Zeilen wie "1234 Wort"? Das ist ja eindeutig ein String, aber mit >> liest man auch erfolgreich einen int ein. Danach stellt man fest, dass es danach aber gar kein Zeilenende folgt. Jetzt müsste man das vorherige Einlesen irgendwie wieder rückgängig machen usw.

    Asonsten such hier mit nach den Posts von Werner Salomon, da gibts viel zu Streams.

    ähm nein "Hallo" steht dann nicht im int. Es kommt halt einfach gar nichts.

    Also: der Stream ist dann im Feherstatus, d.h. wenn du if (stream) machst, kommt false heraus (und stream.fail() ist auch false). Daher liest man normalerweise mit while (stream >> variable) {...} ein. Und wenn am Ende stream.eof() true ist, lief alles gut. Und während stream.fail true ist, kannst du nicht weiter lesen und musst erst wieder clear aufrufen.



  • wob schrieb:

    Meine nicht unbedingt effiziente, aber schnell geschriebene Standardlösung wäre, getline zu verwenden und dann einfach in einer for-loop mit isdigit testen es nur eine Zahl ist (bzw. vorne noch +- zulassen bei Länge >= 2)

    Davon will ich mal abraten. Viele Anfänger nutzen getline nur weil etwas Zeilenweise in einer Datei steht. Dabei ist es doch so, dass eine Datei ein Format hat und das gibt vor, was erwartet wird. Das Format ist hier Zahl + String ohne Whitespaces + beliebig viele Whitespaces dazwischen. Und wenn das Format sagt, es kommt eine Zahl vor, dann nehme ich ein Datentyp für eine Zahl.



  • out schrieb:

    Ich geb dir mal eine einfache Lösung. Du versuchst nun alles zu kommentieren, und postest dann deine Kommentare dazu. Wenn du etwas nicht kennst/verstehst, fragst du mal google.

    #include <iostream>
    #include <fstream>
    #include <string>
    using namespace std;
    
    int main()
    {
    	int zahl;
    	string str;
    
    	for (ifstream file("test.txt");;)
    	{
    		if (file >> zahl)
    			cout << zahl << '\n';
    		else if(file.fail())
    		{
    			file.clear();
    			if (file >> str)
    				cout << str << '\n';
    		}
    		else if (file.eof())
    			break;
    	}
    
    }
    

    danke! hab btw versucht zu googlen wurde daraus aber nicht schlau 😉 jetzt muss ich nur noch herausfinden wieso es kein + oder - nimmt aber hast mir mega weitergeholfen danke nochmal



  • Aus welchen Codeteilen wurdest du nicht schlau?



  • out schrieb:

    Davon will ich mal abraten. Viele Anfänger nutzen getline nur weil etwas Zeilenweise in einer Datei steht. Dabei ist es doch so, dass eine Datei ein Format hat und das gibt vor, was erwartet wird. Das Format ist hier Zahl + String ohne Whitespaces + beliebig viele Whitespaces dazwischen. Und wenn das Format sagt, es kommt eine Zahl vor, dann nehme ich ein Datentyp für eine Zahl.

    Das Format ist hier aber gerade unbekannt.

    Angenommen, da steht "1234abcd" - ohne irgendwelche Whitespaces. Soll dann wirklich Zahl, String erkannt werden? Ist das nicht eher nur ein String und kein int? Ist überhaupt "int" als solcher gemeint oder wird hier nach "Zahl" gefragt? Daher: erstmal klären, wie genau denn hier gelesen werden soll.

    Ich persönlich habe eine Abneigung gegen streams und finde es kompliziert, sie richtig zu nutzen. Andererseits sehen die Lösungen mit Streams, wenn sich jemand damit auskennt, auch oft ganz elegant aus. Das wäre aber definitiv keine Anfängeraufgabe mehr.

    Bonusfrage: ist "2147483648" ein int (wenn numeric_limits<int>::max()=2147483647) - und warum wird nicht analog zu "1234abcd" nur "214748364" als Zahl und "8" als weitere Zahl erkannt? Also, sowas bitte alles bedenken. Daher ist die Aufgabenstellung mir nicht eindeutig genug.



  • Ich habe einfach kombiniert, dass er ein Anfänger ist und es sich deswegen wohl um einfache Strings aus Buchstabenfolgen handelt.

    Ich stimme dir vollkommen zu. Die Aufgabestellung und das Format ist viel zu unpräzise, und unterm Strich, keine Anfängeraufgabe. Und dann sind wir wieder bei SeppJs Post bzgl. guter Literatur... und drehen uns im Kreis 😃

    @seb1234: Wir meinen hier nichts böse, es soll nur ein deutlicher Hinweis für dich sein, dass C++ keine einfache Sprache ist und du ohne guter Literatur verloren bist. Wenn du ins Programmieren einsteigen willst, gibt es deutlich einfachere Sprachen.


Anmelden zum Antworten