Anzeige:
Ergebnis 1 bis 13 von 13

Thema: ausgelesene Zahlen anders darstellen

  1. #1
    Registrierter Benutzer Avatar von The EYE
    Registriert seit
    15.12.2008
    Ort
    Hameln
    Beiträge
    332

    ausgelesene Zahlen anders darstellen

    Hallo liebes Forum!

    Ich habe mal wieder ein C++ Problem.

    Folgende Situation:
    Ich habe eine Datei (mit Einsen und Nullen, siehe Anhang), aus der ich ein bestimmes Array aus Einsen und Nullen auslesen und diese dann wieder ausgeben möchte.
    Das klappt auch schon.

    Zwei Dinge stören mich noch, bzw kann ich nicht umsetzen:
    1. Die Darstellung. In der Konsole wird alles hintereinander ausgegeben. Ich hätte es gerne so, dass die Ausgabe auf der Konsole der Ansicht in der Datei entspricht. Also die Zeilenwechsel eingehalten werden. Meine einzige Idee war mit einer if-Bedingung, hat aber nicht so geklappt, wie erhofft.
    2. Als nächstes würde ich gerne alle eingelesenen Einsen als * ausgeben und alle eingelesenen Nullen als Leerzeichen. Da habe ich leider überhaupt keine Idee.

      Hier noch der Code:
      Code:
      #include <iostream>
      #include <fstream>
      using namespace std;
      
      int main(){
      	const int zeilen = 20;
      	const int spalten = 51;
      	float z_auslesen[zeilen][spalten];
      	
      	ifstream datei;
      	datei.open("../Dateien/datei.txt");
      
      	for (int i = 0; i < zeilen; i = i + 1) // Zeilen
      	{
      		for (int j = 0; j < spalten; j = j + 1) // Spalten
      		{
      			datei >> z_auslesen[i][j]; // auslesen
      		}
      	}
      
      	datei.close();
      
      	for (int i = 0; i < zeilen; i = i + 1) // ausgeben
      	{
      		for (int j = 0; j < spalten; j = j + 1)
      		{
      			cout << z_auslesen[i][j];
      		}
      	}
      
      return 0;
      }
      Ich hoffe wieder auf gute Vorschläge und eure Hilfe

      Gruß Max

    ¹: Erstelle bitte ein richtiges Minimalbeispiel
    ²: Ich nutze Ubuntu 14.04, TeX Live 2014 & Kile 2.1.3

  2. #2
    Registrierter Benutzer Avatar von John W
    Registriert seit
    29.01.2010
    Beiträge
    211
    Bitte sehr:
    Code:
    #include <iostream>
    #include <fstream>
    using namespace std;
    
    int main(){
        const int zeilen = 20;
        const int spalten = 51;
        char z_auslesen[zeilen][spalten];
        
        ifstream datei;
        datei.open("./datei.txt");
    
        for (int i = 0; i < zeilen; ++i) // Zeilen
        {
            for (int j = 0; j < spalten; ++j) // Spalten
            {
                datei >> z_auslesen[i][j]; // auslesen
            }
        }
        datei.close();
        char outchar;
        for (int i = 0; i < zeilen; ++i) // ausgeben
        {
            for (int j = 0; j < spalten; ++j)
            {
                        if (z_auslesen[i][j] == '0')
                            outchar = ' ';
                        else if (z_auslesen[i][j] == '1')
                            outchar = '*';
                        else
                            continue;
                        cout << outchar << " ";
            }
            cout << endl;
        }
    
    return 0;
    }
    Beachte, dass sich float nicht als Datentyp für Zeichen eignet! Ich habe das zu char umgewandelt, weil die Auswahl des auszugebenen Zeichens immer in den else-Teil springt (continue, d.h. das Zeichen wird nicht ausgegeben; evtl. willst du das rausnehmen).

  3. #3
    Registrierter Benutzer Avatar von The EYE
    Registriert seit
    15.12.2008
    Ort
    Hameln
    Beiträge
    332
    Hey!

    Danke für die schnelle Hilfe!

    Ich habe das Programm noch etwas umgeschrieben, da es doch noch nicht ganz funktioniert hat mit den Umbrüchen. Eine andere Datei zum Einlesen macht das deutlich (Anhang).

    Code:
    #include <iostream>
    #include <fstream>
    using namespace std;
    
    int main(){
    	
    	const int zeilen = 20; // zeilen
    	const int spalten = 51; // spalten
    	int z_auslesen[zeilen][spalten]; // ausgelesene Zahl
    	
    	ifstream datei;
    	datei.open("../datei2.txt");
    
    	for (int i = 0; i < (zeilen-1); i = i++) // zeilen
    	{
    		for (int j = 0; j < spalten; j = j++) // spalten
    		{
    			datei >> z_auslesen[i][j]; // Array auslesen
    		}
    	}
    
    	datei.close();
    
    	for (int i = 0; i < (zeilen-1); i = i++) // ausgeben der Werte
    	{
    		for (int j = 0; j < spalten; j = j++)
    		{
    			if (z_auslesen[i][j] == 0)
    			{
    				cout<<" ";
    			}
    			else 
    			{
    				cout<<"*";
    			}		
    		}
    		cout<<"endl";
    	}
    
    return 0;
    }
    Nochmal vielen Dank für die zügige Antwort!

    Gruß Max
    ¹: Erstelle bitte ein richtiges Minimalbeispiel
    ²: Ich nutze Ubuntu 14.04, TeX Live 2014 & Kile 2.1.3

  4. #4
    Registrierter Benutzer Avatar von John W
    Registriert seit
    29.01.2010
    Beiträge
    211
    Autsch, bei dir hapert es etwas mit C++-Kenntnissen.
    1. endl heißt "endline", nicht als String quoten, sondern wirklich std:endl verwenden.
    2. i=i++ -> ganz böse, da wird Blödsinn ausgeführt! Stattdessen ++i in for-Schleifen verwenden; Beispiel dazu:
    Code:
    int i = 0;
    cout << i++ << endl;
    cout << i++ << endl;
    cout << ++i << endl;
    cout << ++i << endl;
    gibt
    Code:
    0
    1
    3
    4
    aus.
    i++ gibt erst den aktuellen Wert von i zurück und erhöht danach, i wird im Speicher gehalten -> langsam, nach Möglichkeit vermeiden.
    ++i hingegen erledigt das in einem Rutsch: Erst erhöhen, dann zurückgeben.
    Solange man keinen Vergleich mit postkrementierten oder prekrementierten Variablen macht, sollte man ++i verwenden.
    Ich hab das nochmal überarbeitet:
    Code:
    #include <iostream>
    #include <fstream>
    using namespace std;
    
    int main()
    {
        const int zeilen = 20; // zeilen
        const int spalten = 50; // spalten
        int z_auslesen[zeilen][spalten]; // ausgelesene Zahl
    
        ifstream datei;
        datei.open("../datei2.txt");
    
        for (int i = 0; i < zeilen; ++i) // zeilen
            for (int j = 0; j < spalten; ++j) // spalten
                datei >> z_auslesen[i][j]; // Array auslesen
    
        datei.close();
    
        for (int i = 0; i < zeilen; ++i) // ausgeben der Werte
        {
            for (int j = 0; j < spalten; j = j++)
                if (z_auslesen[i][j] == 0)
                    cout<<" ";
                else 
                    cout << "*";
            cout << endl;
        }
        return 0;
    }
    Allerdings bin ich durch die merkwürdigen Konstrukte wie i < (zeilen-1) etwas verwirrt, der Sinn erschließt sich mir nicht...

    Gib am Besten zu der Beispieldatei auch die Beispiellösung.
    Geändert von John W (02-11-2010 um 22:53 Uhr)

  5. #5
    Registrierter Benutzer Avatar von jeebee
    Registriert seit
    01.01.2005
    Ort
    Bern || Zürich
    Beiträge
    540
    Zitat Zitat von John W Beitrag anzeigen
    i++ gibt erst den aktuellen Wert von i zurück und erhöht danach, i wird im Speicher gehalten -> langsam, nach Möglichkeit vermeiden.
    ++i hingegen erledigt das in einem Rutsch: Erst erhöhen, dann zurückgeben.
    Solange man keinen Vergleich mit postkrementierten oder prekrementierten Variablen macht, sollte man ++i verwenden.
    Wobei allerdings jeder halbwegs moderne C(++) Compiler für ein i++, wo der Rückgabewert nicht gebraucht wird, genau den gleichen Code (Assembly/Objectcode) wie für ein entsprechendes ++i generiert!

    Fazit: Dass i++ langsam ist, ist heute nicht mehr wahr.
    Geändert von jeebee (03-11-2010 um 00:23 Uhr)
    my very own 128 bit integer
    C4 D3 B8 A8 9E A0 C6 EC 7D EC A8 15 28 D1 92 58
    more information

  6. #6
    Registrierter Benutzer Avatar von John W
    Registriert seit
    29.01.2010
    Beiträge
    211
    Ich wusste nicht, dass Compiler das können - aber ist dennoch good practice. Und ++i lässt sich auch leichter lesen als i=i++...

  7. #7
    Registrierter Benutzer Avatar von The EYE
    Registriert seit
    15.12.2008
    Ort
    Hameln
    Beiträge
    332
    Zitat Zitat von John W Beitrag anzeigen
    Autsch, bei dir hapert es etwas mit C++-Kenntnissen.
    Auf jeden Fall, ich lerne es auch gerade
    Zitat Zitat von John W Beitrag anzeigen
    1. endl heißt "endline", nicht als String quoten, sondern wirklich std:endl verwenden.
    Was meisnt du hiermit genau? Vllt mal zeigen/Beispiel, dann weiß ich vllt was du meinst.
    Zitat Zitat von John W Beitrag anzeigen
    i++ gibt erst den aktuellen Wert von i zurück und erhöht danach, i wird im Speicher gehalten -> langsam, nach Möglichkeit vermeiden.
    ++i hingegen erledigt das in einem Rutsch: Erst erhöhen, dann zurückgeben.
    Solange man keinen Vergleich mit postkrementierten oder prekrementierten Variablen macht, sollte man ++i verwenden.
    Wie i erhöht war mir klar, dass diese Methode jedoch langsamer ist (bzw ja wohl eher war) wusste ich nicht, danke! Habe darüber gar nicht nachgedacht und die Erhöhung mit i++ von meiner Informatik Dozentin übernommen...
    Zitat Zitat von John W Beitrag anzeigen
    Allerdings bin ich durch die merkwürdigen Konstrukte wie i < (zeilen-1) etwas verwirrt, der Sinn erschließt sich mir nicht...

    Gib am Besten zu der Beispieldatei auch die Beispiellösung.
    Ich habe zeilen und spalten als Konstante definiert. Ich fange in der for Schleife mit 0 an zu zählen. bei
    Code:
    for (int i = 0; i < zeilen; i = i++)
    würde von 0-zeilen gezählt werden. Habe den code überarbeitet, indem ich die entsprechenen Zähler bei 1 beginnen lasse.

    Musterlösung gibt es (jedenfalls noch) nicht, das (und noch eine Erweiterung) muss erst bis Ende der Woche fertig sein.

    Code:
    #include <iostream>
    #include <fstream>
    using namespace std;
    
    int main(){
    	const int zeilen = 20;
    	const int spalten = 51;
    	float z_auslesen[zeilen][spalten];
    	
    	ifstream datei;
    	datei.open("../Dateien/datei.txt");
    
    	for (int i = 1; i < zeilen; i = i + 1) // Zeilen
    	{
    		for (int j = 0; j < spalten; j = j + 1) // Spalten
    		{
    			datei >> z_auslesen[i][j]; // auslesen
    		}
    	}
    
    	datei.close();
    
    	for (int i = 1; i < zeilen; i = i + 1) // ausgeben
    	{
    		for (int j = 0; j < spalten; j = j + 1)
    		{
    			cout << z_auslesen[i][j];
    		}
    	}
    
    return 0;
    }
    Gruß Max
    ¹: Erstelle bitte ein richtiges Minimalbeispiel
    ²: Ich nutze Ubuntu 14.04, TeX Live 2014 & Kile 2.1.3

  8. #8
    Registrierter Benutzer Avatar von jeebee
    Registriert seit
    01.01.2005
    Ort
    Bern || Zürich
    Beiträge
    540
    Zitat Zitat von John W Beitrag anzeigen
    Ich wusste nicht, dass Compiler das können - aber ist dennoch good practice. Und ++i lässt sich auch leichter lesen als i=i++...
    Ja, i=i++ ist auf jeden Fall Blödsinn. Und ++i ist afaik C++ good practice, während i++ eher C good practice ist.
    my very own 128 bit integer
    C4 D3 B8 A8 9E A0 C6 EC 7D EC A8 15 28 D1 92 58
    more information

  9. #9
    Registrierter Benutzer Avatar von John W
    Registriert seit
    29.01.2010
    Beiträge
    211
    Zitat Zitat von The EYE Beitrag anzeigen
    Musterlösung gibt es (jedenfalls noch) nicht, das (und noch eine Erweiterung) muss erst bis Ende der Woche fertig sein.
    Du wirst doch wohl wissen, wie die Ausgabe aussehen soll?

  10. #10
    Registrierter Benutzer
    Registriert seit
    12.10.2005
    Beiträge
    18
    Zitat Zitat von The EYE Beitrag anzeigen
    Ich habe zeilen und spalten als Konstante definiert. Ich fange in der for Schleife mit 0 an zu zählen. bei
    Code:
    for (int i = 0; i < zeilen; i = i++)
    würde von 0-zeilen gezählt werden. Habe den code überarbeitet, indem ich die entsprechenen Zähler bei 1 beginnen lasse.
    Wenn die Zählung der Zeilen mit 0 beginnt (wie es in C und C++ meiner Meinung nach üblich ist, da Arrays mit Index 0 beginnen), ist die Begrenzung mit "i < zeilen" richtig. Du bearbeitest die Zeilen 0, 1, 2, ... 17, 18, 19 - also genau die angegebenen 20 Zeilen.

    Wenn Du Deine Zählung mit Zeile eins beginnst, wird das ganze komplizierter und unübersichtlicher, da Du die Arrays größer dimensionieren müsstest.

    Viele Grüße
    Werner

  11. #11
    Registrierter Benutzer Avatar von The EYE
    Registriert seit
    15.12.2008
    Ort
    Hameln
    Beiträge
    332
    Hey!

    Es gibt Neuigkeiten, musste doch wieder etwas ändern und ja, ich habe ein Bild der Ausgabe. Melde mich wieder, habe gerade keine Zeit und wollte nur schnell Bescheid geben!

    Gruß Max
    ¹: Erstelle bitte ein richtiges Minimalbeispiel
    ²: Ich nutze Ubuntu 14.04, TeX Live 2014 & Kile 2.1.3

  12. #12
    Registrierter Benutzer Avatar von The EYE
    Registriert seit
    15.12.2008
    Ort
    Hameln
    Beiträge
    332
    So, das Problem beim Weglassen von zeilen-1 ist, dass dann eine Zeile zu wenig angezeigt wird.

    Es funktioniert mit der Ausgabe jetzt auch alles so weit. Weitere Probleme werden sicher folgen

    Ich habe mal ein Bild des Musterbeispiels in den Anhang gepackt.

    Außerdem eine neue Datei zum Einlesen (die zur Ausgabe passt).

    Gruß Max
    ¹: Erstelle bitte ein richtiges Minimalbeispiel
    ²: Ich nutze Ubuntu 14.04, TeX Live 2014 & Kile 2.1.3

  13. #13
    Registrierter Benutzer Avatar von John W
    Registriert seit
    29.01.2010
    Beiträge
    211
    LOL - wir hatten die Lösung schon... Lediglich die Spaltenangabe hat nicht gepasst.
    Code:
    #include <iostream>
    #include <fstream>
    using namespace std;
    
    int main()
    {
        const int zeilen = 20; // zeilen
        const int spalten = 51; // spalten
        int z_auslesen[zeilen][spalten]; // ausgelesene Zahl
    
        ifstream datei;
        datei.open("../datei2.txt");
    
        for (int i = 0; i < zeilen; ++i) // zeilen
            for (int j = 0; j < spalten; ++j) // spalten
                datei >> z_auslesen[i][j]; // Array auslesen
    
        datei.close();
    
        for (int i = 0; i < zeilen; ++i) // ausgeben der Werte
        {
            for (int j = 0; j < spalten; j = j++)
                if (z_auslesen[i][j] == 0)
                    cout<<" ";
                else 
                    cout << "*";
            cout << endl;
        }
        return 0;
    }

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •