Programmschleife wird zur Endlosschleife
-
Hi wir haben eine kleine Aufgabe bekommen um folgendes Programm zu schreiben.
Soweit funktioniert alles, jedenfalls beim ersten durchlauf. An der Programmschleife hängts. Geb ich ne Null ein, wirds korrekt abgebrochen, ansonsten entsteht eine Endlosschleife! Was ist falsch? Eigentlich sollten es ja beliebig viele Durchgänge sein!#include <iostream> int ersetze_zeich(char*, char, char); int main() { char str[50], c_old, c_new; int id, answer = 1; while(answer) { std::cout << "--- Zeichenkette eingeben [max. 50] ---" << std::endl; std::cin.get(str, 50); std::cout << "Altes Zeichen?" << std::endl; std::cin >> c_old; std::cout << "Neues Zeichen?" << std::endl; std::cin >> c_new; if(id = ersetze_zeich(str, c_old, c_new) != -1) { std::cout << "Zeichenkette: " << str << std::endl; std::cout << "Index: " << id << std::endl; } else std::cout << "Fehler: Zeichen nicht gefunden!" << std::endl; std::cout << "Den Spass nochmal?" << std::endl; std::cin >> answer; }; } int ersetze_zeich(char* s, char zei_alt, char zei_neu) { int i = 0; while(s[i] != '\0') { if(s[i] == zei_alt) { s[i] = zei_neu; return i; } ++i; } return -1; }
-
Tja, ist schon scheiße, wenn man nicht weiss, das in C/C++ alles was nicht 0 ist als true gewertet wird. Wenn du eine bestimmte Anzahl an Durchgängen erzielen willst, rat ich zu einer For-Schleife.
mfg. der b00nbuster
-
Schön schön, das ist mir schon bekannt und genauso wars auch gedacht ... nur bei Null soll das Programm beendet werden (hätte man das durchaus aus dem code erkennen können) ... allerdings kann ich dann im Programm keine Werte mehr eingeben und es wird auch nicht gefragt, ob nochmal oder nicht ... es rattert eben einfach nur in einer Endlosschleife durch bis ich es abschiesse. Das ist das Problem! Trotzdem Danke für deine fachmännische Hilfe!
MfG
-
ich wette, du kennst folgendes nicht:
- debugger
- programm mit cout/printf/puts spicken, um den ablauf zu ergruendenlerne beides.
-
Also, ich kann auch noch nicht so gut C++ aber n paar Schritte weiter bin ich schon...
1.)
Binde "using namespace std" ein, so ersparst du dir bei Funtkionen der iostream das std!!!
2.)
Versuch ein bischen Ordnung in deinen Code zu bringen.
-für dich nud
-für andere(mindestens so, das es halbwegs gut aussieht wenn du es hier reinstellst)
3.) Dein Programm ist bei mir voll funktionstüchtig, mit 2 Ausnahmen:
- Es ersetzt nur den ersten Buchstaben den er findet (Ein [Hallo] [l] [n] wird dann [Hanlo] nicht [Hanno] !!!! )
- Die Schleife, sollte man bei der Abfrage "Den Spaß nochmal?" 1 oder was anderes eingeben ausser 0, dreht durch. Alle anderen Schleifen spinnen.
Lösungen:
- Gebe den Index und das teil veränderte Wort in der Funktion aus.
#include <iostream> using namespace std; void ersetze_zeich(char*, char, char); int main() { char str[50], c_old, c_new; int answer = 1; while(answer) { cout << "--- Zeichenkette eingeben [max. 50] ---" << endl; cin >> str; //cin.get weggemacht weil ich es nciht kenne, sry cout << "Altes Zeichen?" << endl; cin >> c_old; cout << "Neues Zeichen?" << endl; cin >> c_new; ersetze_zeich(str, c_old, c_new); cout << "\n\nDen Spass nochmal?" << endl; cin >> answer; } return 0; } void ersetze_zeich(char* s, char zei_alt, char zei_neu) { int i = 0, isGut=0; while(s[i] != '\0') { if(s[i] == zei_alt) { s[i] = zei_neu; cout << "\nZeichenkette: " << s << endl; cout << "Index: " << i << endl; isGut=1; //Hilfswert zur Überprüfung ob Bst vorhanden } ++i; } if (isGut == 0) cout << "Fehler: Zeichen nicht gefunden!" << endl; cout << "\nFertiges Wort: " << s; //Ist jetzt Void da die Überprüfung in der Funktion stattfindet. }Dein Problem mit der Schleife ist für mich unerklärlich und ich habe auch einiges ausprobiert. Egal was passiert, der übergeht alle cin´s ohne sie abzufragen!!!
-
naja, eigenlich ist die lösung nicht
Lösungen:
- Gebe den Index und das teil veränderte Wort in der Funktion aus.
Denn, die "Gui" Logik ist ausserhalb einer Funktion. Die Funktion selber sollte nur das machen, was sie machen soll. Oder möchtest du eine Funktion von std::string verwenden, welche dir immer irgendwelche zeichen ausgibt??? nein, also
Da fällt mir noch ein "ersetze_zeich" ist nciht grad ein toller fkt, name der alle zeichen ersetzen soll
Wenn du ihm schon fehler auszählst dann weise ihn auch unbedingt auf solche fehler hin!
if(id = ersetze_zeich(str, c_old, c_new) != -1) { // aha überprüfung mit "=" statt "=="das beste ist ja
seine Fkt
int ersetze_zeich(char* s, char zei_alt, char zei_neu) { int i = 0; while(s[i] != '\0') { // unwichtig } return -1; // gibt immer "-1" zurück, was normalerweise bedeutet, dass was schiefgelaufen ist. }dann in der if
if(id = ersetze_zeich // aha was soll id sein? ist nicht initialisiert!if(ersetze_zeich(str, c_old, c_new) != -1) { // ist aber immer gleich, da die fkt immer -1 liefertjetzt check ich auch dein "id"
entweder man macht
if(ersetze_zeich(str, c_old, c_new) != -1) { die rückgabe gleich testen ( guter weg )oder ( mit zwischenspeichern )
id = ersetze_zeich(str, c_old, c_new); // hier erhählt id einen wert ( immer -1 :( ) if(id == != -1) { // hier wird überprüft
-
ProzProg schrieb:
if(id = ersetze_zeich(str, c_old, c_new) != -1)Die Anweisung weist id das Ergebnis des Vergleichs zu - false (0) bei gefunden, true (1) bei Fehler. Das ist wohl nicht das, was du eigentlich wolltest - da solltest du Klammern verwenden ("if((id=erstze_...)!=-1)".
Was die Endlosschleife angeht, empfehle ich mal einen Debugger, um die Arbeit des Programms verfolgen zu können.
-
die funktion get() ist müll. die versetzt den eingabestream in den fehlerzustand, wenn sie eine leerzeile einliest. und da im fehlerzustand alle stream-funktionen schlicht garnichts tun kommt es zur endlosschleife. du mußt statt dessem getline() nehmen.
die leerzeile, die get() einliest, kommt von cin<<answer. das liest nur die zahl aber nicht das anschließende new-line mit ein. deswegen bleibt nach cin<<answer eine leerzeile im eingabepuffer zurück. die leerzeile kannst du mit ignore(0,'\n') entfernen.
außerdem solltest du dich mal mit der string-klasse beschäftigen. der aufwand lohnt sich.
#include <iostream> using namespace std; // macht das leben leichter int ersetze_zeich(char*, char, char); int main() { char str[50], c_old, c_new; int id, answer = 1; while(answer) { cout << "--- Zeichenkette eingeben [max. 50] ---" << endl; cin.getline(str, 50); cout << "Altes Zeichen?" << endl; cin >> c_old; cout << "Neues Zeichen?" << endl; cin >> c_new; if(id = ersetze_zeich(str, c_old, c_new) != -1) { cout << "Zeichenkette: " << str << endl; cout << "Index: " << id << endl; } else cout << "Fehler: Zeichen nicht gefunden!" << endl; cout << "Den Spass nochmal?" << endl; cin >> answer; cin.ignore(0,'\n'); // igroriere alle zeichen bis einschließlich '\n' }; } int ersetze_zeich(char* s, char zei_alt, char zei_neu) { int i = 0; while(s[i] != '\0') { if(s[i] == zei_alt) { s[i] = zei_neu; return i; } ++i; } return -1; }
-
Nichts für ungut und danke für die Beteiligung, aber die einzigen, die hier das wirkliche Problem erkannt haben sind CStoll und Konfusius. Der Rest ist teils Unsinn und teils Müll, denn bei diesen paar Zeilen (einfachen) Codes kann eigentlich nicht viel falsch verstehen ... ich suche lediglich nahc der Lösung dieses trivialen Problems...
1. Kennst du denn Sinn von Namespaces?
2. Der K & R Style ist vollkommen in Ordnung, für mich und andere!
3. Genauso soll es laut Aufgabenstellung auch sein, bis auf das Problem, was du hier endlich auch erkannt hast!@unknow_error_in_mfcd.dll
1. Der Prototyp ist mir vorgegeben => der Funktionsname muss so lauten!
2. Was du erzählst ist Unsinn, return bricht eine Funktion ab => wird die Bedingung der if - Abfrage innerhalb der while - Schleife erfüllt, kommt auch ein richtiger Index an!
3. Die Bedeutung von id geht aus dem Code hervor, sie speichert das Ergebnis des Funktionsaufrufs und gleichzeitig wird in der if - Abfrage überprüft, ob jenes Ergebnis ungleich -1 ist. Mann muss das nicht trennen, wie dir dein Irrglaube vieleicht sagt!Hinweis an euch beide:
"Wenn man keine Ahnung hat, einfach mal die Fresse halten!" Dieter Nuhr
Ich weis die Priorität der Operatoren nich aus dem Kopf und hab sie auch nicht im Stroustrup nachgeschlagen. Klar mit Klammern ist es natürlich eindeutig, aber id wird ein korrekter Index zugewiesen, wenn das Zeichen tatsächlich vorhanden ist.
Mhmm ein deratiges Problem ist mir bei der Arbeit mit Streams noch nicht aufgefallen und beim lesen meiner Referenz kann ich das auch nicht so richtig nachvollziehen. Aber ich werde mich dahingehend mal mehr informieren und vorerst deinen Code testen. Danke für die eigentliche Lösung des Problems! Nebenbei, im Normalfall nutze ich ausschließlich std::string, nur gibt es mir hier die Aufgabenstellung so vor. Ich bin schon etwas niedergeschlagen, dass ich an so einer Kleinigkeit hängenbleibe
. Naja passiert wohl...
-
ProzProg schrieb:
Ich weis die Priorität der Operatoren nich aus dem Kopf und hab sie auch nicht im Stroustrup nachgeschlagen.
Dann solltest du das mal nachholen - oder den Experten vertrauen
(und die sagen dir: Die Zuweisungsoperatoren (=, +=,...) stehen an vorletzter Stelle der Rangfolge - das einzige, was noch geringeren Vorrang hat, ist der Komma-Operator.Klar mit Klammern ist es natürlich eindeutig, aber id wird ein korrekter Index zugewiesen, wenn das Zeichen tatsächlich vorhanden ist.
Bist du dir da ganz sicher?
-
daß das newline im eingabepuffer zurückbleibt und bei der nächsten eingabe zicken mach ist "der" klassiker unter den anfängerfehlern, sowohl in c wie auch in c++. da gibts hier im forum schon unzählige threads dazu

du solltest getline() anstelle von get() nehmen. der unterschied zwischen beiden methoden ist, daß get() daß newline am ende der zeile nicht einliest sondern im puffer zurücklässt! get() sowie getline() setzen das failbit des streams, wenn sie kein zeichen aus dem stream konsumieren. bei get() führt das dazu, daß zweite aufruf nichts einliest, da der erste aufruf das new-line ja nicht eigelesen hat. damit wird das failbit gesetzt. und wenn das failbit gesetzt ist, dann tun die streamfunktionen schlicht garnichts, solange bis es wieder gelöscht wird. das führt dann zur endlosschleife.
EDIT: vorherige erklärung war murks. hab nochmal im standard nachgeschaut.