Ausgabefehler

Karlter

Mitglied
Hey Leute, ich habe hier momentan mit einer kleinen Implementierung zu kämpfen, welche ich fast vollständig gelöst habe. Allerdings schaffe ich es nicht die Ausgabe gemäß der Aufgabenstellung zu coden. Ich stehe irgendwie etwas auf dem Schlauch. Ich habe schon so viel probiert aber komme nicht darauf wie ich es schaffe, dass das Wort "Emoticon = " gemäß der Vorgabe nur ein einziges mal in der Ausgabe steht und und danach dann die Zeichen geprintet werden. Wenn ich ein Syso. mit "Emoticon = " in die Schleife packe wird es natürlich mehrfach ausgegeben, das geht also schon mal nicht. Wenn ich es aber davor packe dann steht es ja direkt beim Programmstart schon in der Konsole - dies soll ebenfalls nicht der Fall sein. Wo liegt hier mein Denkfehler? (wird wahrscheinlich sehr trivial sein :D) Folgenden Code habe ich bereits:

Danke für Euren Input!

public class Emoticon {

public static void main(String[] args) {
/** Das Programm "Emoticon" gibt eine Zahlenreihe als Emoticon wieder.
* Erstelldatum: 06.04.2024
*/

Scanner scanner = new Scanner(System.in);
System.out.print("Zahlen: ");

do {

int zahl = scanner.nextInt();
System.out.print((char) zahl);

} while (scanner.hasNext());


}

}
 

Anhänge

  • Bildschirmfoto 2024-04-15 um 10.32.08.png
    Bildschirmfoto 2024-04-15 um 10.32.08.png
    106,8 KB · Aufrufe: 0

KonradN

Super-Moderator
Mitarbeiter
Bei so Problemen ist es (wie immer) wichtig, dass man das Problem im Detail analysisiert. Da hilft es, das Problem aber dann auch die Lösung in Worten möglichst detailiert zu beschreiben.

Was ist denn das Problem bzw. was soll gemacht werden? Wie würdest Du es einem Menschen erklären?

Ich kann Dir nur empfehlen, dies so durchzuspielen. Die Lösung in dem konkreten Problem wird dir nicht generell helfen, so ein Problem zu lösen!

Wenn Du es einem Menschen erklären würdest, dann würdest Du etwas sagen wie: "Nur bei der ersten Zahl gibst Du zuerst "Emoticon = " vor dem Zeichen aus."

Durch so eine Formulierung findest Du dann einen Lösungsansatz. Du brauchst eine Erkennung, bei der wievielten Zahl Du bist, d.h. Du gehst hin und zählst z.B. mit, bei der wievielten Zahl Du bist. Das wäre ein möglicher, genereller Ansatz.

Aber generell solltest Du aufpassen:
a) hasNext oder solltest Du nicht hasNextInt nutzen?
b) Du solltest auch prüfen, ob die Zahl in einem bestimmten Bereich ist
c) ggf. nachdenken über unterschiedliche andere Schleifen statt der do while Schleife ...
 

Karlter

Mitglied
Hallo @KonradN. Erstmal vielen Dank für deinen erneuten Input. Allerdings stehe ich jetzt noch mehr auf dem Schlauch als vorher :D Ich verstehe deine Ansätze aber assoziiere z.B die Eingrenzung des Wertebereichs direkt mit einer If-Abfrage. Und wenn du auf andere Schleifen anspielst, dann käme da ja nur noch die for-Schleife in Frage (while-Schleife ist ja fast genauso wie die do-while) und das macht für mich dann noch weniger Sinn, da ich ja die Durchgänge der Schleife nicht kenne - oder doch? Und in der Ausgabe steht ja explizit, dass sie auch ohne If-Abfragen gelöst werden kann, das verwirrt mich nun etwas... Wie erkenne ich denn bei welcher Zahl ich gerade bin ohne dann if-else zu nutzen? Mir wäre jetzt sowas in den Kopf gekommen - ich zähle irgendwie mit bei welcher Zahl ich bin und dann:

if(i == 1){
System.out.print("Emoticon: " + (char)i);
} else {
System.out.print((char)i);
}

Aber ohne If Abfragen wird das schwer :D
 

KonradN

Super-Moderator
Mitarbeiter
Erst einmal tut es mir leid, wenn ich Dich auch etwas verwirrt habe - das Problem bei einfachen Aufgaben ist für mich, dass ich nicht zu viel von einer Lösung vorgeben will und das macht es teilweise sehr schwer. Und ich muss gestehen: Ich habe dien Hinweis mit der if Bedingung übersehen. Evtl. war das der entscheidende Punkt, der Dir das Leben schwer gemacht hat.

Bezüglich Schleife habe ich auf die while Schleife abgezielt. Dazu evtl. nur einmal kurz der Hintergedanke von mir:

Du hast derzeit eine Schleife / Logik die so aussieht:

Code:
do {
  if (ersterDurchlauf) {
    Mache etwas speziell für ersten Durchlauf
  }
  Mache was, was in jedem Durchlauf gemacht werden soll
} while (Bedingung für Schleife)

Das kannst Du umwandeln in etwas wie:
Code:
Mache etwas speziell für ersten Durchlauf
while (Bedingung für Schleife) {
  Mache was, was in jedem Durchlauf gemacht werden soll
}

Du kannst also nach der Ausgabe eine erste Zahl einlesen.
Dann kannst Du die einmalige Ausgabe machen (Emoticon =).
Dann kommt die Schleife: So lange die Zahl gültig ist:
a) gib die Zahl als Zeichen aus
b) lies die nächste Zahl ein

Da hast Du dann tatsächlich kein if Bedingung gebraucht.

a) hasNext oder solltest Du nicht hasNextInt nutzen?
Zu dem Hinweis evtl. noch ein Wort: Wenn Du Zahlen lesen willst, dann solltest Du auch prüfen, ob es eine nächste Zahl gibt. Die Idee dahinter ist, dass Du so eine Exception vermeiden kannst. Du verifizierst also erst die Eingabe ehe Du versuchst, diese direkt als Zahl zu lesen. (Kannst Du ja ausprobieren: Gib einfach "hallo" ein oder so).

Das ist aber für die Aufgabe erst einmal irrelevant, denn diese Überprüfungen sind nicht Bestandteil. Wenn Du den Pseudocode anschaust, dann siehst Du kein "Prüfe, ob eine Zahl vorliegt". Du brauchst also weder einen hasNext Aufruf noch einen hasNextInt Aufruf.

Und als generellen Hinweis: Teilweise kann es sinnvoll sein, erst einmal eine Lösung zu schreiben, die funktioniert. Dann kann man im nächsten Schritt immer noch überlegen, ob man ohne if Anweisung auskommen kann.

Und ganz böser Trick: Du kannst ohne if Anweisung alles machen:
Code:
while (Bedingung) {
  // Mach was Du willst
  break; // Verlasse Schleife
}

Ist das gleiche wie:

if(Bedingung) {
  // Mach was Du willst
}

Natürlich ist das nicht Sinn der Aufgabe! Aber du kannst so ein if 1:1 durch ein while ersetzen. if / else wäre dann zwei dieser whiles - einmal while(Bedinung) und einmal while(!Bedingung) ....


Generelle Überlegung hier wäre also mehr etwas wie: Wenn Du Schleifendurchläufe hast und der erste oder letzte Durchlauf ist etwas besonderes, dann kann man darüber nachdenken, das evtl. vor bzw. hinter die Schleife zu ziehen.
 

Karlter

Mitglied
Vielen lieben Dank für Eure Hilfe. Jetzt hats klick gemacht und ich habe es hinbekommen! :) Im Nachhinein sieht es super Simpel aus, allerdings wäre ich nicht darauf gekommen, die Ausgabe des ersten Zeichens separat außerhalb der Schleife zu kodieren. Ich habe das ganze jetzt so umgesetzt: (das mit dem hasNextInt() wäre doch dann also hier sinnvoller als hasNext() - hab ich das richtig verstanden?)

Java:
public class Emoticon {
    
    public static void main(String[] args) {
        /** Das Programm "Emoticon" gibt eine Zahlenreihe als Emoticon wieder.
         * Erstelldatum: 06.04.2024
         */
        
        Scanner scanner = new Scanner(System.in);
        System.out.print("Zahlen: ");
        int zahl = scanner.nextInt();
        System.out.print("Emoticon = " + (char)zahl);
        
        while(scanner.hasNextInt() && zahl >= 32 && zahl <= 126) {
            
            zahl = scanner.nextInt();
            
            System.out.print((char)zahl);
            
        }   
        
    }
    
}
 

KonradN

Super-Moderator
Mitarbeiter
Ohne es getestet zu haben würde ich sagen, dass dies so nicht korrekt ist. Das Problem dürfte sein, dass er eine Zahl mehr erwartet als notwendig.
Also einfach einmal das erste Beispiel probieren: Nach der 31 bricht er nicht ab sondern er erwartet noch eine weitere Zahl.

Da Du eh keine Fehlerbehandlung machst, kannst Du das hasNextInt() ganz weglassen. Und da Du keine if Verwenden sollst, ist eine solche Prüfung auch nicht in der Aufgabe vorgesehen (würde ich sagen. Denn wenn, dann müsste so ein Check auch vor dem ersten nextInt Aufruf statt finden).

Wenn Du es dennoch mit testen wolltest, dann wäre die Prüfung ans Ende zu stellen:
while(zahl >= 32 && zahl <= 126 && scanner.hasNextInt()) {
Dann würde er beim ersten Beispiel bei der 31 abbrechen da 31 nicht >= 32 ist und daher die übrigen Bedingungen nicht mehr ausgewertet werden.

Aber dass sowas Sinn macht, kannst Du mit einem Test ausprobieren. Du kannst z.B. eingeben:
47 hallo
Da würde er dann für die 47 die Ausgabe machen und dann die Abarbeitung beenden. (Was aber vom Aufgabentext nicht gefordert ist. Da hast Du also ein Verhalten implementiert, das nicht spezifiziert ist.

Und das es nicht ausreicht merkst Du bei der Eingabe von:
hallo 47
Da bekommst Du eine Exception, da "hallo" nun einmal keine gültige int Zahl ist.


Edit: Wenn man nur kurz im Forum drauf schaut. Bei so einer Umstellung hat man dann keine Exception mehr, aber das Beispiel mit der Eingabe "47 hallo" würde kein "/" ausgeben für die 47. Da das folgende Element keine int Zahl ist, kommt er nicht zu der Ausgabe in der Schleife.
Daher macht der Check so nicht wirklich Sinn.
 

Jw456

Top Contributor
Wieso das prüfen mit hasNextInt das gibt dir doch nur ein boolean zurück.
Was soll dann das weiter prüfen mit grösser kleiner 32, 126 die Zahl hast du ja zu dem Zeitpunkt noch nicht.
Nur den boolean Wert. Aber nicht den int.
 

MarvinsDepression

Bekanntes Mitglied
Also ich halte die gestelte Aufgabe für einen Anfänger für ganz schön knifflig. Auch ich als "nicht-mehr-ganz-blutiger-Anfänger" hab da meinen Kopf ein bischen anstengen müssen, allen Anforderungen gerecht zu werden.
Meine zwei Tipps:
1. im Schleifenkopf kann eine Wertzuweisung mit einer Bedingung kombiniert werden, z.B. while ( (a = ... ) > 0 ) -> erst wird a ein Wert zugewiesen, dann wird 'größer 0' verglichen.
2. um das geforderte Ausgabebild zu erreichen, ist es ggf. einfacher, sich das Emoticon zunächst in einem geeigneten Datentyp zusammenzusetzen und erst im Anschluss auszugeben.
und
es muss nicht alles in eine Methode gequetscht werden.
 

Ähnliche Java Themen


Oben