C++ Kreditkartennummer überprüfen

Okay, danke schonmal, dass die Stackkorruption weg ist.

Allerdings scheint immernoch ein Fehler im Programm zu sein, den ich nciht finde.

Ich habe zB eine Kreditkartennummer, die definitv gültig sein muss, weil sie aus der Aufgabenstellung kommt
4509472140549006

Gebe ich diese ein kommt raus, dass es KEINE gütlige ist..... Ich bin verzweifelt.........

Hier der aktuelloe Code:
Code:
// Kreditkarte.cpp : Definiert den Einstiegspunkt für die Konsolenanwendung.
//

#include "stdafx.h"
#include <iostream>
#include <stdlib.h>

using namespace std;

int main()
{

	char Feld[17];
	int zahl = 15;
	
	cout << "Bitte Kreditkartennummer eingeben:" << endl;
	cout << endl;
	cin >> Feld;
	cout << endl;


	int zw1 = 0, zw2 = 0, zw3 = 0, zwges = 0;
	int pruefziffer, rest, einer, zehner;
	

	for(int i = 0; i <= zahl; i++)											
		{															
			if ((i == 0) || (i == 2) || (i == 4) || (i == 6) || (i == 8) || (i == 10) || (i == 12) || (i == 14))
				{
					zw3 = Feld[i] * 2;
					if(zw3 >= 10)
						{
							zehner = zw3 / 10;
							einer = zw3 % 10;
							zw3 = zehner + einer;
							zw1 = zw1 + zw3;
						}
					else
						{
							zw1 = zw1 + zw3;
						}
				}
			else
				{
					zw2 = zw2 + Feld[i];						
				}
		}

	zwges = zw1 + zw2;							

	rest = zwges % 10;
	pruefziffer = 10 - rest;

		
	if(Feld[15]==pruefziffer)
	{
		cout << "Dies ist eine moegliche Kreditkartennummer" << endl;
	}
	else
	{
		cout << "Dies ist keine moegliche Kreditkartennummer!" << endl;
	}

	cin.ignore();
	getchar();
	return 0;

}
 
Hast du dir mal das Feld und die Pruefziffer ausgeben lassen?
Vermutlich geht das vergleichen von char mit int nicht gut.
 
Moin,
Und schließlich wird dann auch in die Variable eingelesen (@vfl_freak: und auch automatisch terminiert).
...
Aber, der C-String feld kann max 15 Buchstaben speichern - da C-Strings mit \0 terminiert sind. Falls man 16 Zeichen eingibt, schreibt man über die Feldgrenze hinaus -> Stackkorruption
ja eben ... derartige Probleme hatte ich hier anfangs schon mal :rolleyes:
Oder meinst Du das [EDIT] mit dem automatischen Terminieren[/EDIT] nur im Zusammenhang mit cin ?

Ich habe zB eine Kreditkartennummer, die definitv gültig sein muss, weil sie aus der Aufgabenstellung kommt
4509472140549006
Die Nummer ist 16 Ziffern lang, aber Du prüfst nur max. 15 Stellen - ist das nicht das Problem ?

Gruß
Klaus
 
Zuletzt bearbeitet:
Allerdings scheint immernoch ein Fehler im Programm zu sein, den ich nciht finde.

Ich habe zB eine Kreditkartennummer, die definitv gültig sein muss, weil sie aus der Aufgabenstellung kommt
4509472140549006

Gebe ich diese ein kommt raus, dass es KEINE gütlige ist..... Ich bin verzweifelt.........
Vermutlich ist einfach deine Prüfungsvorschrift falsch.

Wie sieht denn die Vorschrift zur Prüfung aus?

Gruß
 
ja eben ... derartige Probleme hatte ich hier anfangs schon mal :rolleyes:
Oder meinst Du das nur im Zusammenhang mit cin ?
Naja, cin speichert fröhlich alles was da kommt an die Adresse der Variablen und terminiert dann den String mit \0. \edit: Ja, das automatische Terminieren meinte ich nur im Zusammenhang mit cin.

Da Feld[15] offenbar eine Prüfziffer ist, darf ja nicht \0 da stehen. Das Feld muss also noch eins größer sein.

@freeak2305:

Das Problem ist, du rechnest da mit Buchstaben ('4' == 52 usw.). Du müßtest die Buchstaben erstmal in Ziffern umwandeln.

Außerdem solltest du noch prüfen ob überhaupt genug Buchstaben eingegeben wurden und ob die Eingabe überhaupt aus Ziffern besteht.

Gruß
 
Zuletzt bearbeitet:
Ich verstehe nicht, was du mir damit sagen willst....Wie gesagt, ich bin da ein totaler Idiot in diesem Gebiet...
Du hast da einen String. Ein String besteht aus Buchstaben bzw. Zeichen.

"0123" <- String
'0' <- Zeichen

Zeichen haben laut ASCII Tabelle einen bestimmten Wert:

'a' => 97
'0' => 48
'1' => 49

usw.

Feld = "4509472140549006"

Feld[0] => '4' => 52

Zum Umrechnen:
C:
int digit = Feld[i] - '0';
Zum Prüfen ob das Zeichen überhaupt eine Ziffer ist:
C++:
#include <cctype>

if (isdigit(Feld[i])) {
  ...
} else {
  // Fehler, kann keine Kred.-Nr. sein.
  ...
}
Gruß
 
Okay, das ist verständlicher für mich(tut mir Leid. Ich bin Systemintegrator und soll in der Anwendungsentwicklung aushelfen....lustig)

So, ich hab nun mal alles komplett umgeschmissen. Hat leider alles nichts gebracht. Der Wurm war trotzdem noch drin. hier nun meine Lösung, die funktioniert, aber ein kleines bisschen umständlicher ist!

Code:
// Kreditkartennummer überprüfen.cpp : Definiert den Einstiegspunkt für die Konsolenanwendung.
//

#include "stdafx.h"
#include <iostream>
#include <stdlib.h>

using namespace std;

int main()
{
	int z1=0, z2=0, z3=0, z4=0, z5=0, z6=0, z7=0, z8=0, z9=0, z10=0, z11=0, z12=0, z13=0, z14=0, z15=0, z16=0;
	int pz=0, summe=0, zwischenerg=0;
	int rest1=0,rest2=0,rest3=0,rest4=0,rest5=0,rest6=0,rest7=0,rest8=0;
	
	cout << "Kreditkartennummer pruefen" << endl;
	cout << endl;
	cout << "Jede Ziffer einzeln, gefolgt von ENTER eingeben" << endl;				//Leider klappte die Version mit einem Array gar nicht
	cout << endl;

	cin >> z1;
	rest1=(z1*2)/10;																//Doppelt gewichtete Ziffern der Kreditkartennummer
	rest1+=((z1*2)%10);																//Erst Zehnerstelle ermitteln, danach die Einerstelle addieren
	cin >> z2;
	cin >> z3;
	rest2=(z3*2)/10; 
	rest2+=((z3*2)%10);
	cin >> z4;
	cin >> z5;
	rest3=(z5*2)/10; 
	rest3+=((z5*2)%10);
	cin >> z6;
	cin >> z7;
	rest4=(z7*2)/10; 
	rest4+=((z7*2)%10);
	cin >> z8;
	cin >> z9;
	rest5=(z9*2)/10; 
	rest5+=((z9*2)%10);
	cin >> z10;
	cin >> z11;
	rest6=(z11*2)/10; 
	rest6+=((z11*2)%10);
	cin >> z12;
	cin >> z13;
	rest7=(z13*2)/10; 
	rest7+=((z13*2)%10);
	cin >> z14;
	cin >> z15;
	rest8=(z15*2)/10; 
	rest8+=((z15*2)%10);
	cin >> z16;
	cout << endl;

	summe = rest1+z2+rest2+z4+rest3+z6+rest4+z8+rest5+z10+rest6+z12+rest7+z14+rest8;	//Quersumme bilden
	zwischenerg = summe % 10;															//Rest ermitteln
	pz = 10 - zwischenerg;																//Prüfziffer errechnen
	
	if(z16 == pz) 
	{ 
		cout << "Moegliche Kreditkartennummer!" << endl;
	}
	else
	{
		cout << "Kreditkartennummer nicht moeglich!" << endl;
	}

	cout << "Pruefziffer = " << pz << endl;
	cout << "Letzte Stelle der Nummer = " << z16 << endl;
	
	cin.ignore();
	getchar();
	return 0;
}
 
Zuletzt bearbeitet:
Okay, das ist verständlicher für mich(tut mir Leid. Ich bin Systemintegrator und soll in der Anwendungsentwicklung aushelfen....lustig)

So, ich hab nun mal alles komplett umgeschmissen. Hat leider alles nichts gebracht. Der Wurm war trotzdem noch drin. hier nun meine Lösung, die funktioniert, aber ein kleines bisschen umständlicher ist!
Was hast du denn gemacht? Du hättest doch einfach nur überall da wo "Feld[..]" steht nur "(Feld[..] - '0')" hinschreiben müssen...

Nicht ganz so umständlich, mit Fehlerprüfung:
C++:
#include <iostream>
#include <string>
#include <cctype>

using namespace std;

int main(int argc, char *argv[])
{
    cout << "Kreditkartennr: ";

    std::string nr;
    if (cin >> nr && nr.size() == 16) {
        int zw1 = 0, zw2 = 0, zw3 = 0;

        for (int i = 0; i < nr.size() - 1; ++i) {
            if (!isdigit(nr[i])) {
                cerr << "ungültige Eingabe\n"
                     << nr << '\n'
                     << string(i, ' ') << '^' << endl;
                return 2;
            } else {
                int digit = nr[i] - '0';

                if (i % 2 == 0) {
                    zw3 = digit * 2;
                    if (zw3 >= 10) {
                        zw3 = (zw3 / 10) + (zw3 % 10);
                    }
                    zw1 += zw3;
                } else {
                    zw2 += digit;
                }
            }
        }
        int p = 10 - (zw1 + zw2) % 10;
        int l = nr[15] - '0';

        if (p == l) {
            cout << "ok" << endl;
            return 0;
        } else {
            cout << "invalid" << endl;
            return 3;
        }
    }

    cout << "Keine gültige Eingabe." << endl;
    return 1;
}
Normalerweise sollte man sich da Funktionen definieren...

Gruß
 
Zurück