Kreditkartenvalidierung
-
Hey Leute ich brauche eure Hilfe!
Ich bin erst seit einigen Wochen mit der Programmierung in Ansi C beschäftigt.
Hab davon auch fast gar keine Ahnung.
Nun sollen wir als erste Aufgabe ein Programm schreiben was Kreditkartennummern prüft.
Es funktioniert soweit nur bei falschen KKN zeigt es nicht die gewünschte Ausgabe an.Hier der Code vllt. kann mir jemand helfen.
Edit* ich denke der Fehler liegt im letztem Abschnitt des Codes.
bei der letzten Verzweigung wird nie die "else" Anweisung ausgeführt#ifdef _MSC_VER #define _CRT_SECURE_NO_WARNINGS #endif #define MIN 13 #define MAX 16 #include<stdio.h> #include<stdlib.h> #include<string.h> int main() // Definition der Variabeln { int flag, i, gesamtsumme, ziffer, mod; char A[] = "Kreditkartennummer eingeben bitte "; //String zur Aufnahme der Kreditkartennummer char X[] = "00000000000000000000"; //String der der Nullen vor der Eingabe einfügt do //annehmende Schleife für Eingabeprüfung { printf("Bitte geben Sie Ihre Kreditkartennummer ein:\n"); flag = 0; gets(A); if (!(strlen(A) >= MIN && strlen(A) <= MAX)) //solange eingabe falsche länge besitzt wird die schleife wiederholt flag = 1; else for (i = 0; i < strlen(A); i++) //zählschleife Stellen der Kreditkarte werden nacheinander geprüft if (!(A[i] >= 48 && A[i] <= 57)) //falsche zeichen laut ascii code schleife wird wiederholt flag = 1; } while (flag); X[20 - strlen(A)] = '\0'; // 0 Terminierung strcat(X, A); //verketten von eingabe und bufferstring gesamtsumme = 0; for (i = 19; i >= 0; i--){ // jede Stelle von rechts wird durchlaufen, zählschleife dekrementiert i mod = i % 2; //modulo 2 an jeder stelle if (mod == 0){ //wenn rest 0 ziffer = (X[i] - '0') * 2; //dann ziffer an der Stelle mal 2 if (ziffer > 9){ //Wenn Zahl größer 9, ziffer = ziffer - 9; //dann wird 9 abgezogen } else{ ziffer = ziffer; } //wenn nicht bleibt die mit 2 multiplizierte Ziffer } else { ziffer = X[i] - 48; }gesamtsumme = gesamtsumme + ziffer; } //Prefixabfrage mittels Zeiger int laenge_Karte, Anzahl_Zeilen_K; int K_Prefix, index_zeiger; char Karte[20] = ""; strcpy(Karte, A); char Karten_Buffer[] = " Dient jeweils zur Aufnahme des entsprechenden Prefix der Karte... und genau mit der Anzahl Zeichen aus K[i][2] "; // Array zum Abegen der KK-Holder char Holder[][20] = { { "Visa" }, { "MASTERCARD" }, { "AMEX" }, { "Discover" }, { "JBC" }, { "Diners Club" } }; int K[][4] = { /*Kartenprefix,Stellenanzahl,Prefixlänge,Index in A[][] */ { 41, 16, 2, 0 }, { 41, 13, 2, 0 }, { 51, 16, 2, 1 }, { 52, 16, 2, 1 }, { 53, 16, 2, 1 }, { 54, 16, 2, 1 }, { 34, 15, 2, 2 }, { 37, 15, 2, 2 }, { 36, 14, 2, 5 }, { 38, 14, 2, 2 }, { 6011, 16, 4, 3 }, { 3, 16, 1, 4 }, { 300, 14, 3, 5 }, }; Anzahl_Zeilen_K = sizeof(K) / sizeof(int) / 4; // Ermittelung der Zeilenanzahl in K index_zeiger = Anzahl_Zeilen_K + 2; // index_zeiger wird in A[index_zeiger] gesetzt, falls er verändert wurde laenge_Karte = strlen(Karte); // Kartenlänge bereitstellen for (i = 0; i < Anzahl_Zeilen_K; i++) { strcpy(Karten_Buffer, Karte); // Buffer mit Karte füllen Karten_Buffer[K[i][2]] = '\0'; // Prefix erzeugen in Abhängigkeit von K[i][2] K_Prefix = atoi(Karten_Buffer); // Typ von char Array nach int if (K_Prefix == K[i][0] && laenge_Karte == K[i][1]) { index_zeiger = K[i][3]; // hier prüfen und schleife bei Erfolg verlassen break; } } if (index_zeiger < 99) printf("Die eingegebene Kreditkarte mit der Kennung %s\nist vom Holder: %s \n", Karte, Holder[index_zeiger]); else printf("Die eingegebene Kreditkarte mit der Kennung %s\nist keinem Holder bekannt!\n", Karte); system("Pause"); return 0; }
-
wie kommst du denn auf die bedingung für die if-Abfrage?
if (index_zeiger < 99)
soweit ich das programm überblickt habe wird dein index_zeiger immer kleiner 99 sein egal ob ein holder gefunden wurde oder nicht.
-
Anzahl_Zeilen_K = sizeof(K) / sizeof(int) / 4; // das ist Müll
-
vielen dank für die schnellen antworten.
dann werde ich die prefixerkennung doch selber machen, umständlich über switch case. meine kenntnisse reichen einfach noch nicht weit genug.
(finde es auch irgendwie bisschen überzogen nach 4 wochen als maschinenbaustudent so etwas können zu müssen)die komplette prefixabfrage ist vom unseren dozenten und er meinte wir sollen die
ruhig mit einbauen(z.b nur noch variablen/feldnamen anpassen).aber jetzt weiß ich wenigstens das der dozent nicht nur menschlich voll daneben ist sondern anscheinend auch nicht die korifee der c programmierung ist als die er sich immer darstellt.
-
Wutz schrieb:
Anzahl_Zeilen_K = sizeof(K) / sizeof(int) / 4; // das ist Müll
wieso ist das müll?
sizeof(K) gibt mir die größe des 2-dimensionalen arrays in byte
sizeof(int) gibt mir die größe eines ints in bytedann ist doch sizeof(k) durch sizeof(int) die anzahl der elemente im array.
und wenn ich das durch die anzahl der spalten teile (also durch 4) bekomme ich die anzahl der zeilen.ich bin auch noch neu in C und sehe daher nicht den fehler. vielleicht könntest du mich da noch etwas aufklären?
@ bonniesranch:
du musst nur die letzte if-abfrage ändern. dann funktioniert es. welche werte kann denn index_zeiger annehmen wenn die karte zu einem der insitute passt?
welchen wert hat index_zeiger wenn kein institut passt?
-
Sowas als Lehrkörper seinen Schülern anzubieten, ist grausame Augenkrätze.
Die Anzahl der Elemente eines Arrays in C zu ermitteln, ist schon sei Urzeiten bekannt:size_t anzahl = sizeof(array) / sizeof(*array); oder meinetwegen size_t anzahl = sizeof(array) / sizeof(array[0]); oder size_t anzahl = sizeof array / sizeof *array;
Das klappt im Gegensatz zur Lehrervariante immer, für jedes Array von jedem Elementtyp.
Wenn MSVC gegeben und auf Nichtportabilität Wert gelegt wird (bei den allermeisten Lehrkörpern der Fall), verwendet man einfach _countof aus (MSVC)stdlib.h.
-
bonniesranch schrieb:
die komplette prefixabfrage ist vom unseren dozenten und er meinte wir sollen die
ruhig mit einbauen(z.b nur noch variablen/feldnamen anpassen).Tja, da hast du Pech gehabt mit deinem Lehrstoffvermittler. Du wirst nichts Vernünftiges lernen.
Ich würde sowas z.B. anbieten:
/* separierbare Funktionalitäten gehören in eine Funktion ausgelagert; sowas nennt man auch Programmdesign */ const char* gibPrefix(const char *nr) /* Kreditkartennummer wird übergeben, Herausgeber wird rückgeliefert */ { const char *Holder[] = { "Visa" , "MASTERCARD" , "AMEX" , "Discover" , "JBC" , "Diners Club" }; const char *K[][2] = { { "41", "0" }, { "41", "0" }, { "51", "1" }, { "52", "1" }, { "53", "1" }, { "54", "1" }, { "34", "2" }, { "37", "2" }, { "36", "5" }, { "38", "2" }, { "6011", "3" }, { "3", "4" }, /* hier kann ja wohl was nicht stimmen, 3 ist diesbzgl. nicht eindeutig */ { "300", "5" } }; int x=sizeof K/sizeof*K; while( x-- ) if( !strncmp(nr,*K[x],strlen(*K[x])) ) return Holder[atoi(K[x][1])]; return ""; }
Außerdem braucht ihr nicht jeder einzeln hier aufschlagen:
http://www.c-plusplus.net/forum/321791-full
-
danke für die erklärung wutz.
Wutz schrieb:
{ "3", "4" }, /* hier kann ja wohl was nicht stimmen, 3 ist diesbzgl. nicht eindeutig */
du hast in deinem array nicht die länge der KKN mit dabei. deshalb ist 3 mehrdeutig. wenn die länge der KKNs dabei ist, dann ist es eindeutig, weil dann nur nummern die mit 3 anfangen und 16 stellen haben von JCB sind.
Wutz schrieb:
Außerdem braucht ihr nicht jeder einzeln hier aufschlagen:
http://www.c-plusplus.net/forum/321791-fulldas problem bei den threads ist doch nicht das selbe. die aufgabenstellung ist auch nur ähnlich. beim anderen thread war ja z.b. gar nicht teil der aufgabe das kreditkarteninstitut zu ermitteln. aber gerade das ist ja hier das problem vom TE
-
Tja, da hast du Pech gehabt mit deinem Lehrstoffvermittler. Du wirst nichts Vernünftiges lernen.
das Gefühl habe ich auch langsam
@bluebird: ich habe den Wert bei der letzten Prüfung auf <14 gestellt, da der
index_zeiger ja maximal auf Zeile 13 zeigen kann.Ein paar testläufe führten zum gewünschten Ergebnis. Ich denke ich lasse es jetzt so..
Auch wenn die Lösung mit Sicherheit nicht sauber ist.trotzdem vielen dank für eure lösunsmöglichkeiten und hilfe!