[C++] Was ist im Code falsch?

blue lord

Mitglied
Folgender Code ist nur ein Beispielprogramm, aber was habe ich in ihm falsch gemacht?

Code:
#include <iostream>
using namespace std;

int main()
{
    char Passwort[5];
    char Passworteingabe[5];
    cout << "Legen Sie ein Passwort 4-stelliges Passwort fest!\n";
    cin >> Passwort;
    cout << "Vielen Dank! Das Passwort wurde gespeicher.\n"; 
    cout << "\nGeben Sie das Passwort ein, um Zugriff auf die Daten zu haben!\n";
    cin >> Passworteingabe;
    if (Passworteingabe[5] == Passwort[5])
    {
        cout << "Das Passwort ist richtig!\n"
                "Sie haben zugriff auf die Daten.\n";
    }
    else
    {
        cout << "Das Passwort ist falsch!\n\a"; 
        cout << "Geben Sie es erneut ein!\n";
    }

    system("Pause");
    return 0;
}

Wenn ich das Programm ausführe, und das richtige Passwort eingebe, kommt trotzdem die Anzeige, dass dieses falsch währe.
 
Hi!

Du machst 2 grundlegende Fehler in folgender Zeile:
if(Passworteingabe[5] == Passwort[5])
1. Du vergleichst nur die beiden sechsten(!) Zeichen der Char-Arrays, nicht die ganzen Strings.
2. Du begehst eine Speicherzugriffsverletzung:
wenn du einen Array wie folgt definierst:
Code:
<type> array[N];
Dann legt der Compiler für dich einen Array vom Typ <type> mit N Elementen an.
Da der erste Index aber 0 ist, muss der letzte N-1 sein. (in deinem Fall 4).

Um die Fehler zu beheben, ändere die Zeile wie folgt:
Code:
if(strcmp(Passworteingabe, Passwort))
Damit sollte das Problem behoben sein.
(Du musst wahrscheinlich noch die string.h includen.)

Gruß
Johannes
 
Hi!

strcmp (Kurzform für StringCompare) ist eine Funktion, die dazu dient als String zu interpretierende Char-Arrays zu vergleichen.

Eine mögliche Implementation wäre folgende:
Code:
#define BOOL int
#define TRUE 1
#define FALSE 0

BOOL strcmp(const char *s1, const char *s2)
{
	while(*s1)
	{
		if(*s1 != *s2)
			return FALSE;
		s1++;
		s2++;
	}
	return TRUE;
}

Gruß
Johannes
 
@revelation:
Eine mögliche Implementation wäre folgende:...
Böse!
Was machst du wenn s2 "kürzer" als s1 ist? Buffzz, --> Zugriffsverletzung :-)
@topic:
Wenn man schon std::cin und/oder std::cout (was ja c++ Streamklasseninstanzen sind) verwendet, dann kann man auch gleich std::string verwenden.
Diese Stringklasse implementiert einen operator ==() um 2 strings zu vergleichen:

Code:
#include <string>

int main(int argc, char** argv)
{
   std::string a;
   std::string b;
   std::cout << "string a eingeben" << std::endl;
   std::cin >> a;
   std::cout << "string b eingeben" << std::endl;
   std::cin >> b;

   if(a==b)
      std::cout << "a und b sind gleich" << std::endl;
   else
      std::cout << "a und b sind ungleich" << std::endl;

   return 0;
}

Gruß Homer
 
Hi!

@Daniel Toplak:

Warum?

Bsp:
Code:
BOOL strcmp(const char *s1, const char *s2)
{
	while(*s1)
	{
		if(*s1 != *s2)
			return FALSE;
		s1++;
		s2++;
	}
	return TRUE;
}

void main()
{
	char *s1 = "abc",
	     *s2 = "a";

	if(strcmp(s1, s2))
		printf("Die Strings waren identisch!\n");
	else
		printf("Die Strings waren verschieden!\n");
}

So jetzt läuft nach dem Aufruf von strcmp die Schleife.

1. Durchlauf :
*s1 ist 'a' -> Schleife wird ausgeführt
*s1 != *s2 <=> 'a' != 'a' -> Falsch, if-Code wird übersprungen
s1++; s2++;

2. Durchlauf
*s1 ist 'b' -> Schleife wird ausgeführt
*s1 != *s2 <=> 'b' != '\0' -> Wahr, FALSE wird zurückgegeben!

Die Funktion arbeitet (fast immer :-)) korrekt! Auch wenn strlen(s2) < strlen(s1), weil sobald der letzte Charakter von s2 ('\0') erreicht wird, unterscheiden sich die Strings an der Stelle und die Funktion und damit die Schleife wird vorzeitig verlassen!

Man müsste am Ende noch ein
Code:
if(*s1 == *s2)
	return TRUE;
else
	return FALSE;
einfügen, da die Funktion ein falsches Ergebnis liefert, wenn s1 kürzer ist als s2, der Anfang von s2 aber gleich s1 ist.
:-)

Gruß
Johannes
 
Zuletzt bearbeitet:
Wenn man schon std::cin und/oder std::cout (was ja c++ Streamklasseninstanzen sind) verwendet, dann kann man auch gleich std::string verwenden.
Da ich erst C++ lerne, weiß ich von std::string nichts.


Wenn ich es wie von revelation geraten mache, wird bei Eingabe eines falschen Passwortes dieses als richtig angesehen. :(

Code:
#include <iostream>
using namespace std;

int main()
{
    char Passwort[4];
    char Passworteingabe[4];
    cout << "Legen Sie ein Passwort 4-stelliges Passwort fest!\n";
    cin >> Passwort;
    cout << "Vielen Dank! Das Passwort wurde gespeicher.\n"; 
    cout << "\nGeben Sie das Passwort ein, um Zugriff auf die Daten zu haben!\n";
    cin >> Passworteingabe;
    if(strcmp(Passworteingabe, Passwort))
    {
        cout << "Das Passwort ist richtig!\n"
                "Sie haben zugriff auf die Daten.\n";
    }
    else
    {
        cout << "Das Passwort ist falsch!\n\a"; 
        cout << "Geben Sie es erneut ein!\n";
    }

    system("Pause");
    return 0;
}
 
Hi,
der Code kann nicht funktionieren, da strcmp bei Gleichheit eine 0 statt eine 1 zurückgibt..
Tip:
Bevor du Bibliotheksfunktionen verwendest schau dir vorher die API an. Dann weißt du besser
bescheid was Sache ist...

Bsp.:
strcmp API

Ausserdem solltest du dich mit den angesprochenen std::string's im Laufe der Zeit vertraut
machen, da sie einen das Leben oft erleichtern und Probleme, die du mit gewöhnlichen char*
Objekten bekommen könntest,vermeiden können..

Gruß

RedWing

//edit revalation sollte seine Funktion danach anpassen das sie dem Standard entspricht...
 
Zuletzt bearbeitet:
Tip:
Bevor du Bibliotheksfunktionen verwendest schau dir vorher die API an. Dann weißt du besser
bescheid was Sache ist...
OK, mache ich.



Jetzt mal eine andere Frage.
Ich habe folgenden Code im Internet gefunden.

Code:
// C++ version of 99 Bottles of beer
// programmer: Tim Robinson timtroyr@ionet.net
// Corrections by Johannes Tevessen

#include <iostream>
using namespace std;

int main()
    {
    int bottles = 99;
    while ( bottles > 0 )
        {
        cout << bottles << " bottle(s) of beer on the wall," << endl;
        cout << bottles << " bottle(s) of beer." << endl;
        cout << "Take one down, pass it around," << endl;
        cout << --bottles << " bottle(s) of beer on the wall." << endl;
        }
    cin.ignore();
    return 0;
    }


Warum kommt, wenn man das Programm ausführt nur 75 bottles of beer und nicht 99?
 
Zurück