Pointer als Rückgabewert eines Unterprogramms



  • Genau betrachtet ist das alles Schrott, was du hier anbietest.
    Ich habe beim Zählen der Fehler bei 10 aufgehört.

    Genau betrachtet, brauchst du überhaupt keinen lokalen Speicher, eingabe kannst du mit fgets und konvertierung kannst du direkt auf *s erledigen, auch scheint mir die Schleife dort irgendwie sinnfrei.



  • Swordfish schrieb:

    Eine for -Schleife die von 0 bis 0 zählt?
    Dir ist klar, daß Bezeichner durchaus mehr als einen Buchstaben lang sein dürfen!?

    die for-Schleife läuft von 0 bis 1 und hat den Zweck aus z.B. "de"(=Deutschland)
    die Zahlen 1314 zu berechnen und als String in ein extra Array zu speichern.
    Schon richtig so,aber darum ging es mir hier nicht.

    Wutz schrieb:

    Genau betrachtet ist das alles Schrott, was du hier anbietest.
    Ich habe beim Zählen der Fehler bei 10 aufgehört.

    Tut mir Leid, dass dich mein Code so aufregt, aber nicht jeder kann soviel Erfahrung besitzen wie du.

    Ich danke allen.
    Ich werde mir eure Vorschläge ansehen und Bescheid geben,wenn es geklappt hat.



  • blacksun schrieb:

    ...
    die Zahlen 1314 zu berechnen und als String in ein extra Array zu speichern.
    Schon richtig so,aber darum ging es mir hier nicht.

    Da sieht keiner was du da berechnen willst.
    Wenn du '0' meinst, schreib auch '0' hin.

    Wie sieht es mit Großbuchstaben aus?

    m[i] = (toupper(*s) - 'A' + 10) / 10 + '0';  // toupper aus ctype.h
    

    Vorher kann man noch mit isalpha() prüfen ob es überhaupt ein Buchstabe ist.



  • mit Übergabe von m (Variable von main) ans Unterprogramm eingabe hat es funktioniert.

    Tatsächlich habe ich vorher versucht eine Pointer zu returnen, der auf eine lokale Variable m zeigte.Das war der Fehler, wie manche es hier richtig erkannt haben.

    Danke nochmals.

    @Dirk:
    die Problematik mit Klein/-Großbuchstaben war mir hier nicht wichtig.
    Ich eigne mir gerade C an und da war mir hier die Pointer-Handhabung wichtiger.
    Aber natürlich sollte man in einem gescheiten Programm alle Möglichkeiten Abfangen.

    Noch ne Kleinigkeit:
    Ich möchte nen 24stelligen String,der nur aus Zahlen besteht,(Pointer f zeigt auf diesen) im Unterprogramm pruefziffer in eine "normale" Zahl umwandeln, um damit was zu berechnen.

    double pruefziffer(char *f)
    double pruefzahl=0;
    
    for(f;*f;f++) pruefzahl= Pruefzahl*10+(*f-48);
    
    pruefzahl=98-fmod(pruefzahl,97);
    
    return pruefzahl;
    }
    

    Ich habe das Problem, dass die Pruefzahl im folgenden Unterprogramm irgendwann(wahrs. wegen unzureichendem Wertebereich des Datentyps Double) irgendwann ungenau wird.f ist wie gesagt der Pointer auf nen 24stelligen String.

    welcher Datentyp kann eigentlich eine 24 stellige Zahl annehmen/berechnen ohne zu runden?
    und mit welchem Format gibt man sowas aus?
    %d für int, %c für Char, %f für Float, %? für 24stellige Zahl?? ???



  • 24 Stellen ist zuviel für jeden handelsüblichen Datentyp in C. Was willst du denn damit rechnen? "Prüfziffer" klingt nicht nach Rechnen.



  • OK,ich erklär mal meine ganze Aufgabe:

    Überprüfen eine IBAN auf Gültigkeit:
    Ich habe ne IBAN-Nummer (zb.de53360200410012345678) in der externen Datei.
    Die IBAN besteht aus
    - Ländercode(2 Stellen)
    - Prüuefziffer(2 Stellen)
    - Bankleitzahl(8 Stellen)
    - Kontonummer(bis zu 10 Stellen,eventuell mit Nullen auf 10 Stellen auffüllen)

    1. Ich hole mir die aus der externen Datei.
    2. ersetze Buchstaben durch a-z durch Ziffern 10 bis 35
    Also a->10,...,d->13,e->14...
    3. Umstellen:
    de53360200410012345678->360200410012345678131400
    Also BLZ, dann Kontonummer, dann "1314" für "de" und 2 abschließende Nullen dazu
    4. 360200410012345678131400 mod 97 = 45
    5. 98-45=53
    6. Vergleiche berechnete Prüzziffern mit 3.und 4.Stelle der vorgegeben IBAN
    falls gleich: alles OK
    falls ungleich: ungültige IBAN

    Ich hoffe es ist jetzt verständlich wozu ich so ne lange Zahl brauche.
    Wobei es bestimmt auch andere Wege gibt.nur welche?



  • blacksun schrieb:

    Ich hoffe es ist jetzt verständlich wozu ich so ne lange Zahl brauche.

    Du suchst nach Kongruenzen.



  • blacksun schrieb:

    Ich habe hier doch die Methode Call by Value mit Rückgabewert Pointer angewandt oder? Oder kann man Pointer nicht mit Return zurückgeben, sondern muss die Call by Reference-Methode anwenden?

    Du hast die lokale Variable m auf dem Stack liegen und der ist nach Rückkehr aus der Methode nicht mehr existent. Sowas kann einem schnell um die Ohren fliegen.

    Du kannst die lokale Variable m statisch anlegen, d.h. diese existiert nur ein einziges Mal, dafür aber auch nach Ende Deiner Funktion:

    static char m[100];
    

    Ciao
    MM


  • Mod

    blacksun schrieb:

    Ich hoffe es ist jetzt verständlich wozu ich so ne lange Zahl brauche.
    Wobei es bestimmt auch andere Wege gibt.nur welche?

    Du beschreibst keine Zahl, sondern eine Ziffernfolge. Sieht zwar beides gleich aus (in den üblichen Darstellungen), ist aber ganz was anderes.

    Faustregeln, wie man Zahlen von Ziffernfolgen unterscheiden kann: Ist die Differenz von zwei dieser Objekten eine sinnvolle Größe? Kann man führende Nullen weglassen? Kann man eine Größe im Oktalsystem darstellen, ohne den Sinn zu verkehren? Das ist hier alles eindeutig nicht der Fall. Ebenso bei Telefonnummern, Postleitzahlen und Kontonummern, die ebenfalls gerne fälschlicherweise als Zahl angesehen werden, obwohl sie Ziffernfolgen sind.

    Behandle Ziffernfolgen wie Zeichenfolgen, deren Zeichen eben bloß Ziffern sein können.



  • SeppJ schrieb:

    Du beschreibst keine Zahl, sondern eine Ziffernfolge. Sieht zwar beides gleich aus (in den üblichen Darstellungen), ist aber ganz was anderes.

    Doch die IBAN wird in eine Zahl umgewandelt um die Prüfsumme zu berechnen. Vielleicht verwechselst du das mit der ISBN(da ist es eine Ziffernfolge).

    BTT: Erstelle ersteinmal die Ziffernfolge in der richtigen Reihenfolge, so wie du es beschrieben hast. Nimm dafür einfach ein int Array der nötigen Länge(24?).
    Danach musst du von hinten nach vorne die Stellen der letztendlichen Zahl berechnen. Als Datentyp probier mal long long int.

    //array = die Ziffernfolge mit Ziffern in der richtigen Reihenfolge
    int i;
    long long int zahl = 0;
    for (i = sizeof (array)-1; i >= 0; i--)
    {
    zahl += pow (10, (sizeof (array) - i)) * array[i];
    }
    

    So in etwa, ist eher Pseudo Code. 🙂
    Für pow benötigst du math.h, damit berechnest du die zehner, hunderter, etc. Stelle der Zahl.


  • Mod

    sacridex schrieb:

    SeppJ schrieb:

    Du beschreibst keine Zahl, sondern eine Ziffernfolge. Sieht zwar beides gleich aus (in den üblichen Darstellungen), ist aber ganz was anderes.

    Doch die IBAN wird in eine Zahl umgewandelt um die Prüfsumme zu berechnen. Vielleicht verwechselst du das mit der ISBN(da ist es eine Ziffernfolge).

    Eine Prüfsumme macht aus einer Ziffernfolge keine Zahl, sondern ist ein weiteres Argument, dass es sich nicht um eine Zahl handelt.



  • @sacridex
    Für eine 24-Stellige Dezimalzahl braucht man ca. 80 Bit zu Darstellung.
    long long hat meist 64 Bt. Reicht also nicht.

    Und statt pow und hinten am Array anzufangen, fängt man vorne an und rechnet immer mal 10. Zumal auch pow (auch für long double) für volle 24 Dezimalstellen nicht ausreicht.



  • Mit C99 liegt die min. garantierte Grenze für unsigned long long int bei 18446744073709551615 bzw. 18446744073709551615ULL, d.h. man kann max. 19 Dezimalstellen bei Integer-Berechnungen damit verwenden.
    Ältere MSVC haben stattdessen (weil kein C99) dafür unsigned __int64.



  • SeppJ schrieb:

    sacridex schrieb:

    SeppJ schrieb:

    Du beschreibst keine Zahl, sondern eine Ziffernfolge. Sieht zwar beides gleich aus (in den üblichen Darstellungen), ist aber ganz was anderes.

    Doch die IBAN wird in eine Zahl umgewandelt um die Prüfsumme zu berechnen. Vielleicht verwechselst du das mit der ISBN(da ist es eine Ziffernfolge).

    Eine Prüfsumme macht aus einer Ziffernfolge keine Zahl, sondern ist ein weiteres Argument, dass es sich nicht um eine Zahl handelt.

    eine zahl ist eine folge von ziffern, wo ist das problem und was soll die haarspalterei?



  • x.x. schrieb:

    eine zahl ist eine folge von ziffern, wo ist das problem und was soll die haarspalterei?

    Ja, aber nicht jede Folge von Ziffern ist eine Zahl. Wer das nicht versteht, addiert auch Telefonnummern.



  • Wenn man rechnen will, benötigt man ein Zahl (interpretierte Ziffernfolge zu einer Basis), um darauf einen Operator (hier wohl 😵 anwenden zu können.
    Die Frage ist bloß, ob man wirklich rechnen muss oder nur vermeintlich und es auch anders geht.
    Mit C99 wie gesagt max. 19 Dezimalstellen, ansonsten muss man zu einer Big-Integer Bibliothek greifen, es gibt mehrere mehr oder weniger handliche.



  • SeppJ schrieb:

    Eine Prüfsumme macht aus einer Ziffernfolge keine Zahl, sondern ist ein weiteres Argument, dass es sich nicht um eine Zahl handelt.

    Lies dir doch bitte erstmal die Definition der IBAN durch, bevor du hier wild rumspekulierst...
    http://de.wikipedia.org/wiki/International_Bank_Account_Number#Validierung_der_Pr.C3.BCfsumme

    btt: Gut, dann reicht long long nicht. Habe es nur vermutet. 😉
    long long long gibts nicht? Bei einem 64bit System dürfte es doch sowas geben?



  • Das hast du nicht verstanden, unsigned long long int nutzt bereits die 64Bit-Breite, denn 264-1 == 0xFFFFFFFFFFFFFFFF == 18446744073709551615



  • Ja, ich weiß, aber das tut es ja auch auf einem 32bit System, deshalb könnte es ja sein, dass es einen Datentyp mit 128bit auf 64bit Systemem gibt, wäre ja in beiden Fällen doppelte Wortbreite.
    Habe schon __int128 probiert, geht aber irgendwie nicht. 😞



  • sacridex schrieb:

    Habe schon __int128 probiert, geht aber irgendwie nicht. 😞

    RTFM von deinem Compiler statt rumzuraten.


Anmelden zum Antworten