Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (WinAPI, Konsole) » Probleme mit Funktionen

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
26.12.2011, 22:16 Uhr
Kain Geinius



Hey Leute, ich bin noch relativ neu in der Programmierung und befasse mich noch mit den Grundlagen von C++ im Erstsemester meines Studiums.
Nun habe ich bei einer Hausaufgabe ein Problem, und zwar funktionieren bei mir die implementierten Funktionen nicht bzw. nur fehlerhaft (mit immer wechselnden Ergebnissen).

Die Hausaufgabe besteht darin von ISBN-10, ISBN-13 die Prüfziffern zu berechnen.

Hier mal mein bisheriger Code:


C++:
#include <iostream>

using namespace std;

void i_13()
{
    int isbn[12]; //isbn ohne pruefziffer
    int zw[12];   //zwischenspeicher
    int zs;       //zwischensumme
    int i;        //index
    int pruefziffer;

//Beispiele: 1. 978344640744-2 ; 2. 978340756277-7 ; 3. 978340415762-4
    cout << "ISBN-13 Nummer ohne Pruefziffer, Bindestriche und Leerzeichen: ";
    std::cin >> isbn[12];

    //erste zahl der isbn bearbeiten...
    i = 0;
    zw[i] = isbn[i] * 1;
    //und in zw abspeichern
    
    do //mache folgendes....
    {
        i++; //index um 1 erhöhen
        zw[i] = isbn[i] * 3; //zweite, vierte ... zahl der isbn bearbeiten und abspeichern
        i++; //index um 1 erhöhen
        zw[i] = isbn[i] * 1; //dritte, fünfte ... zahl der isbn bearbeiten und abspeichern
    }while(i != 12);    //...bis der index 12 ist
    
    zs = 0;  //zs den wert 0 geben
    for(i = 0; i <= 12; i++) //index auf 0 setzen und je schleifendurschlauf um 1 erhöhen bis index = 12 ist
    {
        zs = zs + zw[i]; //zs den wert von aktuellen zs + zw des aktuellen indexes zuweisen
    }
        
    pruefziffer = (10 - zs % 10) % 10;
    
    cout << pruefziffer << endl; //pruefziffer ausgeben

    cin.clear();
};

void i_10()
{
    int isbn[9];    //Array zur Speicherung der ISBN-Nummer
    int i = 0;      //index des Arrays
    int i2 = 0;    
    int pruef[9];    //Prüfziffer- Zwischenergebniss,
    int mul;        //Multiplikator
    int zw = 0;     //Zwischensumme
    int pruefziffer;
//Beispiele: 1. 340756227-2 ; 2. 349913599-X ; 3. 312932260-4
    cout << "ISBN-10 Nummer ohne Pruefziffer, Bindestriche und Leerzeichen: ";
    std::cin >> isbn[9];
    
    //
    //Berechnung überprüfen!!!
    //
    
    
    for(mul = 1; mul <= 9; mul++)//erhöht den multiplikator in jedem durchlauf um 1
        pruef[i] = isbn[i] * mul;    //multipliziert die jeweilige index-zahl mit dem dazugehörigen multilikator
        i++;                        //erhöht den index in jedem durchlauf
                                    //im array pruef werden jeweils die produkte abgespeichert
    
    for(i = 0; i <= 9; i++)        //in jedem durchlauf wird der index von ruef um 1 erhöht
        zw = zw + pruef[i];        //die aktuelle index- zahl wird zur derzeitige zwischensumme
                                    //addiert und in zw gespeichert
    
    pruefziffer = zw % 11;            //zwischensumme modulo 11 wird in pruefziffer gespeichert
    
    if(pruefziffer == 10)           //wenn pruefziffer == 10 wird bei der ausgabe die pruefziffer durch ein X ersetzt.
        cout << "X" << endl; //ausgabe der isbn und -X
    else
        cout << pruefziffer << endl; //ausgabe der isbn und - prufziffer

    cin.clear();
};

int main(int argc, char* argv)
{    
    int wahl;

    cout << "Ihre Wahl bitte:" << endl;
    cout << "1- ISBN-10" << endl;
    cout << "2- ISBN-13" << endl;
    cout << "3- Programm verlassen" << endl;
    cin >> wahl;

    switch(wahl)
    {
        case 1:
            i_10();
            break;
        case 2:
            i_13();
            break;
        case 3:
            cout << "Programm wird beendet." << endl;
    };


    system("PAUSE");
    return 0;
}



Könnt ihr mir sagen was ich falsch gemacht habe bzw was ich besser machen könnte? stehe scheinbar grad echt auf nem Schlauch.

Ich bedanke mich schonmal für die Antworten
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
26.12.2011, 23:21 Uhr
0xdeadbeef
Gott
(Operator)


Au weia. Dann gehen wir mal von oben nach unten durch: der erste Fehler, der mir auffällt, ist

C++:
    int isbn[12]; //isbn ohne pruefziffer

    ...

    std::cin >> isbn[12];  


Hier solltest du deine Vorlesungsaufzeichnungen und das Lehrmaterial noch mal konsultieren; wie Arrays funktionieren, scheint dir nicht so richtig klar zu sein. isbn[12] ist nach der Deklaration kein Bezeichner für das gesamte Array (dieses heißt isbn), sondern wäre ein Element des Arrays, wenn dieses nicht auf 12 Einträge (also Indices 0-11) begrenzt wäre. So, wie es da steht, wird undefiniertes Verhalten erzeugt.

Etwas weiter unten passiert der selbe Fehler erneut:

C++:
    do //mache folgendes....
    {
        i++; //index um 1 erhöhen
        zw[i] = isbn[i] * 3; //zweite, vierte ... zahl der isbn bearbeiten und abspeichern         i++; //index um 1 erhöhen
        zw[i] = isbn[i] * 1; //dritte, fünfte ... zahl der isbn bearbeiten und abspeichern
    }while(i != 12);    //...bis der index 12 ist


hier wird zw[12] = isbn[12] gesetzt, und da sowohl zw als auch isbn auf 12 Einträge begrenzt sind (der letzte gültige also zw[11] bzw. isbn[11] ist), würde der Code hier undefiniert, wenn er es nicht weiter oben schon wäre. Zusätzlich dazu werden hier schon bevor über die Arraygrenzen hinaus gelesen bzw. geschrieben wird Werte verwendet, die vorher nicht initialisiert werden. Das Ergebnis der betreffenden Berechnungen ist daher unspezifiziert.

Gleiches gilt hier:

C++:
    for(i = 0; i <= 12; i++) //index auf 0 setzen und je schleifendurschlauf um 1 erhöhen bis index = 12 ist
    {
        zs = zs + zw[i]; //zs den wert von aktuellen zs + zw des aktuellen indexes zuweisen
    }


Des weiteren bin ich mir ziemlich sicher, dass

C++:
    cin.clear();


nicht macht, was du vermutest; es löscht lediglich den Fehlerstatus des Stream-Objekts std::cin. Ich nehme an, du suchst nach cin.ignore(numeric_limits<streamsize>::max(), '\n');. In diesem Fall wäre es aber insgesamt einfacher und sauberer, erst die ganze Zeile in einen String zu holen und die Ziffern daraus in das Zahlenarray, mit dem du arbeiten willst (bzw. einen vector) zu zerlegen, dann löst sich das Problem in Wohlgefallen auf.

Beheb das erst mal, dann mach dich an die andere Funktion. Dort betreibst du den selben Kram ja erneut.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 26.12.2011 um 23:22 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
28.12.2011, 23:15 Uhr
Kain Geinius



Hi, also ich hab versucht das Problem mit den Array zu lösen, aber wenn ich etwas daran ändere kommen immer Fehlermeldungen wie z.B. "kein passender >> Operator konnte gefunden werden" oder "isbn ist ein nicht gültiger Bezeichner"... kannst du mir mal sagen wie ich das richtig mache? (Die Aufgaben funktionieren dennoch alle, wenn auch mit falschem Ergebniss)

Aber ich habe auch eine weitere Frage wegen der Berechnungen,
also hier erstmal wie man die Prüfziffern berechnet:

ISBN-13:
Zum Berechnen der Prüfziffer müssen die Zahlen der Zahlenkette mit gerader Position mit
3 multipliziert werden und die Zahlen ungerader Position mit 1 multipliziert.
Die Teilergebnisse sollen addiert werden und von diesem Ergebniss die letzte Zahl muss von 10
subtrahiert werden. Die Daraus resultierende Zahl ist die Prüfziffer.
------------------------------------------------------------------------------------------
ISBN-10:
Zum Berechnen der Prüfziffer müssen die einzelnen Zahlen der Zahlenkette
mit einem Faktor von 1 (bei der ersten) bis 9 (ber der letzten Zahl) multipliziert
und die Teilergebnisse addiert werden. Diese ganzzahlige Summe soll mit 11 dividiert
werden. Der Divisionsrest ist die Prüfziffer.
------------------------------------------------------------------------------------------
EAN:
Es werden die Ziffern von rechts nach links abwechselnd mit 3 und 1 multipliziert.
Die jeweiligen Ergebnisse werden addiert. Die Differenz zur nächsthöheren Zehnerpotenz
ergibt die Prüfziffer.

------------------------------------------------------------------------------------------

Wie im oberen Quellcode von mir zu sehen ist habe ich bereits versucht die Berechnungen mit Schleifen zu realisieren etc., aber irgendwie will nicht das richtige Ergebnis rauskommen. (Habe aber die Berechnungsvorgänge etwas kürzer fassen können).

Ich bedanke mich im vorraus für die Hilfe von dir/euch
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
29.12.2011, 13:47 Uhr
~f.-th.
Gast


Nicht schön, aber selten

C++:
void i_10()
{
    int isbn[9];    //Array zur Speicherung der ISBN-Nummer ohne Prüfziffer
    int i = 0;      //index des Arrays

    int zw = 0;     //Zwischensumme
    int pruefziffer;
//Beispiele: 1. 340756227-2 ; 2. 349913599-X ; 3. 312932260-4
    cout << "ISBN-10 Nummer ohne Pruefziffer, Bindestriche und Leerzeichen: ";
    for(i = 0; i < 9; i++)
        std::cin >> isbn[i];    // na ja zum Üben -> besser C++ Strings

    for(i = 0; i < 9; i++)
        zw = zw + isbn[i] * (i + 1);  //Zwischensumme Zahl für Zahl summieren

    pruefziffer = zw % 11;

    if(pruefziffer == 10)            //wenn pruefziffer == 10 wird bei der ausgabe die pruefziffer durch ein X ersetzt.
        cout << "X" << endl;         //ausgabe der isbn?? und -X
    else
        cout << pruefziffer << endl; //ausgabe der isbn?? und - prufziffer
}




Es gibt auf jeden Fall bessere Lösungen
Bei der Eingabe musst du jede Ziffer einzeln bei diesem Quelltext bestätigen. Das solltest du wahrscheinlich ändern. Ist aber nicht schwer, wenn du dir Mühe gibst.
Eine der Beispiel-ISBN ist ...
Auch geänderte Kommentare im Quelltext beachten.
Bei den Kommentaren das mit der Klein- und Grossschreibung besser sortieren.

Ein wenig beratungsresistent bist du schon, oder?

MfG f.-th.

P.S.: vorraus
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (WinAPI, Konsole) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: