Char Array , erstes Zeichen verloren



  • Hi Leute, ich bin grad dabei, eine Textdatei auszulesen. Funktioniert auch alles super, nur wenn ich versuche das ganze via Zeiger an die main zu liefern geht mir das erste Zeichen im char array verloren. Sprich, wenn ich in der main puffer[0] aufrufe. bei puffer[1] und [2] kommen jeweils die richtigen Zeichen.
    Könntest ihr bitte mal drüberschaun bzw. einen Tipp geben, wie man das ganze einfacher gestalten kann?Lerne noch C++ und steh grad total aufem Schlauch, wo das Problem liegt.

    Danke schonmal 🙂

    int main()
    {
    	char puffer[256];
    	menue();
    	eingabe(&puffer[0]);
    	cout << puffer[0];
    	getch();
    }
    
    void eingabe(char *puffer)
    {
    	int eingabe;
    	cout << "Bitte waehlen sie aus: ";
    	cin >> eingabe;
    	cout << endl;
    	switch(eingabe)
    	{
    	case 1:
    		cout << "Der Text wird eingelesen!" << endl;
    		texteinlesen(&puffer[0]);
    		break;
    	case 2:
    		cout << "Der Text wird verschluesselt!" << endl;
    		break;
    	case 3:
    		cout << "Der Text wird entschlusselt!" << endl;
    		break;
    	case 4:
    		cout << "Beenden" << endl;
    		exit(0);
    		break;
    	default:
    		cout << "Error" << endl;
    	}
    }
    void texteinlesen(char *puffer)
    {
    	fstream quelle;
    	quelle.open ("C:\\text.txt", ios::in| ios::binary);
    	if(quelle.good())
    	{
    	while(quelle.getline(puffer, sizeof(puffer)))
    	{
    		int i = 0;
    		cout << puffer;
    		puffer[i] = *puffer;
    	}
    	}
    	else
    	{
    		cout << "Fehler beim oeffnen!" << endl;
    	}
    }
    

  • Mod

    while(quelle.getline(puffer, sizeof(puffer)))
        {
            int i = 0;
            cout << puffer;
            puffer[i] = *puffer;
        }
    

    Dies hier kommt dir nicht irgendwie komisch vor? Was ist denn wohl i? Und was soll das überhaupt bewirken?

    Allgemein: Gibt es irgendeinen Grund, warum du dir selbst dies antust? std::string benutzen.



  • Ui. Also, zunächst sticht mir das hier ins Auge:

    while(quelle.getline(puffer, sizeof(puffer)))
        {
            int i = 0;
            cout << puffer;
            puffer[i] = *puffer;
        }
    

    hier ist sizeof(puffer) die Länge eines Zeigers, nicht die des Buffers, auf den er zeigt (d.h. vermutlich 4 oder 8). Im Schleifenkörper ist i immer 0, d.h.

    puffer[i] = *puffer;
    

    macht gar nichts.

    Ich vermute aber, dass das Problem, in das du läufst, Folgendes ist: Nach

    int eingabe;
        cout << "Bitte waehlen sie aus: ";
        cin >> eingabe;
    

    steckt das, was nach der Zahl eingegeben wurde, noch im Eingabestrom - inklusive des Zeilenendes. Das heißt, selbst wenn du da nur eine Zahl eingibst, steckt "\n" noch in std::cin und wird beim nächsten getline erst ausgelesen.

    Aber was ganz anderes - warum plagst du dich mit char-Arrays rum und benutzt nicht einfach std::string?

    (SeppJ hätte wahrscheinlich eine Ahnung, aus welchem Buch du das hast 😉 )


  • Mod

    seldon schrieb:

    (SeppJ hätte wahrscheinlich eine Ahnung, aus welchem Buch du das hast 😉 )

    Ja, habe ich, aber ich wollte abwarten, was die Frage nach dem "warum?" als Antwort ergibt. Ich vermute mal, dass auf Beispiele in dem Buch das nicht genannt werden darf verwiesen wird.



  • SeppJ schrieb:

    while(quelle.getline(puffer, sizeof(puffer)))
        {
            int i = 0;
            cout << puffer;
            puffer[i] = *puffer;
        }
    

    Dies hier kommt dir nicht irgendwie komisch vor? Was ist denn wohl i? Und was soll das überhaupt bewirken?

    Allgemein: Gibt es irgendeinen Grund, warum du dir selbst dies antust? std::string benutzen.

    Ist mir direkt nach dem abschicken des posts aufgefallen. Leider konnte ich nicht editieren. Naja C++ machen wir in der Schule, und da wurde es uns so gezeigt.
    Das i fehlt an dieser Stelle, weil ich schon zich Sachen am ausprobieren bin, und es vorhin vergessen hab wieder dazu zu packen.
    Aus einem Buch habe ich diesen Quelltext nicht, hab ich selbst gemacht.
    Ist aber nur ein kleiner teil des Programms. Später muss ich das ausgelesene noch verschlüsselt in eine andere Datei schreiben.

    Ich glaube, ich weiß worauf ihr hinauswollt, mit dem Buch, vielleicht c++ von a-z 😃 ? ja ich hab dieses Buch, aber lese es kaum bis garnicht.
    Aber wie gesagt der entstandende Quelltext ist nicht aus dem Buch.


  • Mod

    sometimes schrieb:

    Naja C++ machen wir in der Schule, und da wurde es uns so gezeigt.

    Dann ist jetzt die entscheidende Frage: Wenn du nun std::string benutzt, ist dein Lehrer dann der Typ der sagt "Wow! Das kannte ich noch gar nicht. Toll, dass du das gefunden hast!" oder der Typ "String gab's damals nicht als ich Programmieren gelernt habe, lernt gefälligst das was ich euch beibringe! Setzen! Sechs!"?



  • So ich wusste doch, das ich hier noch registriert bin 🙂

    Ich weiss nicht, ob das uns beigebrachte dem Aktuellen entspricht.
    Jedenfalls hab ich damals für andere Aufgaben ebenfalls ein bisschen im Internet gesucht und etwas verwendet, was wir nicht gemacht hatten, wobei aber das selbe Ergebnis bei rauskaum. Man wurde nur angemosert mit"Soweit sind wir noch nicht oder das ist nicht das, was wir gemacht haben". Da bleibt mir dann eben nichts anderes übrig.
    Wollt mir jetzt zu Weihnachten nen gutes Buch holen Der C++ Programmierer eventuell noch den C++ Primer, falls er sich finden lässt, um mal das aktuelle zu lernen.
    Aber ich drifte hier zuweit ab^^

    @seldon

    steckt das, was nach der Zahl eingegeben wurde, noch im Eingabestrom - inklusive des Zeilenendes. Das heißt, selbst wenn du da nur eine Zahl eingibst, steckt "\n" noch in std::cin und wird beim nächsten getline erst ausgelesen.

    ist das irgendwie ein Hinweis?
    ich glaub was dem entsprechen könnte hatten wir noch nicht.
    Meinst du vielleicht cin.ignore()
    Hab das noch aus einem C++ Buch in Erinnerung, es setzt den Textcursor zum Anfang zurück - oder so ähnlich.
    Das vielleicht?



  • Mal an einem Stringstream demonstriert (ein Stringstream ist wie jeder andere Ein- bzw. Ausgabestrom, nur holt er seine Daten aus bzw. schreibt sie in einen String):

    #include <iostream>
    #include <sstream>
    #include <string>
    
    int main() {
      std::istringstream str_in("123\n"
                                "abc\n"
                                "def\n");
    
      int zahl;
    
      str_in >> zahl;
      std::cout << "Zahl: " << zahl << '\n';
    
      std::string zeile;
    
      for(int i = 1; std::getline(str_in, zeile); ++i) {
        std::cout << "Zeile " << i << ": " << zeile << '\n';
      }
    }
    
    // Ausgabe:
    // 
    // Zahl: 123
    // Zeile 1:
    // Zeile 2: abc
    // Zeile 3: def
    

    Das Einlesen in zahl nimmt nur (!) die Zahl aus dem Eingabestrom. Es bleibt in diesem Fall "\nabc\ndef\n", also drei Zeilen, von denen die erste leer ist.

    Ein Zeilenrest lässt sich aus einem Eingabestrom beispielsweise so entfernen:

    #include <limits>
    
    // ...
    
    eingabestrom.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    

    ...was soviel bedeutet wie "ignoriere gaaaanz viele Zeichen aus eingabestrom, aber nicht weiter als bis zum nächsten Zeilenumbruch". Alternativ bietet es sich an, die Eingabe zeilenweise aus std::cin zu lesen und per Stringstream zu parsen, und natürlich kann man auch einfach eine Zeile einlesen und ignorieren.



  • Okey danke für eure Hilfe, muss das jetzt nur noch auf die Streams anpassen



  • So hab ein neues Problem, hab das Programm etwas umgeschrieben.Bin doch erstmal noch bei den streams geblieben.
    Es öffnet die Textdatei und liest sie auch aus(nicht ganz oder fehlerhaft)
    Es werden prompt ab dem dritten Zeichen keine Zeichen mehr übernommen(also dem element [2]. Ich find aber nirgends einen Fehler und der Quelltext scheint für mich demnach auch logisch. Ich bitte euch nochmal drüber zu schaun. Ich glaub er geht von selbst in einen anderen Bereich und holt sich da irgendwelche Werte, weil in der eingetragen Textdatei sind wirwarr Zeichen.

    danke 🙂

    void eingabe(char *puffer)
    {
    	int eingabe;
    	cout << "Bitte waehlen sie aus: ";
    	cin >> eingabe;
    	cout << endl;
    
    	switch(eingabe)
    	{
    	case 1:
    		texteinlesen(&puffer[0]);
    		cout << "Der Text wurde erfolgreich eingelesen!" << endl;
    		cout << endl;
    		cout << puffer[0];
    		cout << puffer[1];
    		cout << puffer[2];
    		cout << puffer[3];
    		cout << puffer[4];
    		break;
    	case 2:
    		textverschluesseln(&puffer[0]);
    		cout << "Der Text wurde erfolgreich verschluesselt!" << endl;
    		cout << endl;
    		break;
    	case 3:
    		cout <<"Der Text wurde erfolgreich entschluesselt!" << endl;
    		break;
    	case 4:
    		cout << "Beenden" << endl;
    		break;
    	default:
    		cout << "Error, Falsche eingabe!!!" << endl << endl << endl;
    	}
    }
    void texteinlesen(char *puffer)
    {
    	fstream quelle;
    	quelle.open ("C:\\text.txt", ios::in| ios::binary);
    	if(quelle.good())
    	{
    		while(quelle.getline(puffer, sizeof(puffer)))
    		{
    
    		}
    	}
    	else
    	{
    			cout << "Fehler beim oeffnen!" << endl;
    	}
    }
    
    void textverschluesseln(char *puffer)
    {
    	fstream ziel;
    	ziel.open ("C:\\text2.txt", ios::in | ios::out | ios::binary);
    	if(ziel.good())
    	{
    		cout << "Datei erfolgreich geoeffnet!" << endl;
    	}
    	else
    	{
    		cout << "Fehler beim oeffenen!" << endl;
    	}
    
    	ziel << puffer[0];
    	ziel << puffer[1];
    	ziel << puffer[2];
    	ziel << puffer[3];
    	ziel << puffer[4];
    	ziel << puffer[5];
    	ziel << puffer[6];
    }
    

Anmelden zum Antworten