Ein char in long int umwandeln

lalalala

Grünschnabel
Hallöchen,
kann mir jemand helfen habe eine Aufgabe die ich nicht lösen kann und überhaupt nicht weiß wie ich anfangen soll :(.

Hier ist sie....

Viele Programme erwarten die Eingaben der Benutzer als String. Es ist dann die Aufgabe
des Programms diese Eingabe zu überprüfen.
Schreiben Sie eine Funktion, die einen String, der eine ganze Zahl darstellt (C-Datentyp:
long int) in den entsprechenden Wert umwandelt. Die Deklaration dieser Funktion ist also:
long int str_to_long(char in[]);
Dabei soll diese Funktion den Parameter in (den String) auf Fehler überprüfen. Es ist auch
zu berücksichtigen, dass der String zu viele Ziffern enthält und auf dem Rechner gar nicht als
long int darstellbar ist.
Das Resultat der Funktion (der Return-Wert) soll sind:
• der entsprechende Wert des Strings, wenn der String fehlerfrei ist.
• der Wert der größten oder kleinsten long int-Zahl, wenn der String fehlerhaft
ist. Die kleinste Zahl wird verwendet, wenn der String am Anfang das Zeichen
'-' besitzt, sonst wird die größte Zahl verwendet.
Schreiben Sie Ihre Funktion so, dass sie unabhängig von einem spezifischen Rechner ist!
Probieren Sie die Funktion in einem kleinen Hauptprogramm, insbesondere wie sie auf Fehler
reagiert.
 
Willkommen bei tutorials.de :)

Schreiben Sie Ihre Funktion so, dass sie unabhängig von einem spezifischen Rechner ist!

Na das ist ja lustig.
Unabhängig von Variablengröße, signed/unsigned und dem Zeichensatz(?).
@all: Gibts eigentlich einen Zeichensatz, der die Ziffern nich hintereinander von 0 bis 9 hat?

Ich würde einem Anfänger zuerst einmal die Aufgabe ohne diesen einen Satz geben und dann eventuell mit.
Nur verständlich, dass du jetzt verwirrt bist :D

Also, generell musst du:
-Eine Variable haben, 0 reinschreiben
-Den String Zeichen für Zeichen durchgehen, bei jedem Zeichen die Variable mal 10 + die aktuelle Ziffer im String nehmen
-Wenn die Variable einen Überlauf hat, Fehler zurückgeben
-Wenn ein Zeichen drin ist, das keine Ziffer ist, auch einen Fehler zurückgeben

Einen Überlauf/zu großen Wert in der Variable erkennst du in dem Fall (du vergrößerst sie ja nur immer mit Multiplikation un Plus), dass nach so einer Rechnung auf einmal ein kleinerer Wert als vorher drin ist.
Ist in C generell so, wenn man über den Größten Wert hinauskommt wird beim kleinsten weitergemacht.

Noch zu beachtenist, dass die Ziffern im String in irgendeinem Zeichensatz (zB Ascii) abgespeichert sind, bei dem die Ziffern in wirklichkeit andere Zahlenwerte haben
Wenn man zB 0 ab Bildschirm sieht, wird das in Wirklichkeit als 48 abgespeichert, 1->49...
Welche Werte die Ziffern wirklich haben, hängt aber auch vom Zeichensatz und somit vom Computer ab.

edit: Compiler spinnt herum, kann dir zurzeit leider kein (getestetes) Beispiel posten
Ich veruchs aber weiter

Gruß
 
Zuletzt bearbeitet:
Die Formulierung der Aufgabenstellung lässt darauf schließen, dass der Aufgabensteller Wert auf Plattformunabhängigkeit legt, d.h. du sollst maximal portabel sein. Dies ist nur mit strikt konformen ANSI C89 möglich. Für den genannten Fall gibt es meines Wissens ausschließlich die Standardbibliotheks-Funktion strtol. Eine Lösung könnte sein:

C:
#include <limits.h>
#include <stdlib.h>

long str_to_long(const char *in)
{
  long l;
  char *e;
  l=strtol(in,&e,10);
  return *e?LONG_MAX:l;
}

Die Aufgabenstellung ist aber ungenau, falls nämlich der String genau LONG_MIN oder LONG_MAX bedeutet, kann durch den Aufruf der Funktion dieser Wert nicht von einem übergebenen String mit einem Über/Unterlauf von <long int> unterschieden werden.
 
Die Aufgabenstellung ist aber ungenau, falls nämlich der String genau LONG_MIN oder LONG_MAX bedeutet, kann durch den Aufruf der Funktion dieser Wert nicht von einem übergebenen String mit einem Über/Unterlauf von <long int> unterschieden werden.

Naja, so lautet aber die Aufgabe.
Bei Schulaufgaben ist es oft sowieso überflüssig, sich über den Sinn Gedanken zu machen.

Und bei einer Schulufgabe (die es ja wahrscheinlich ist) sollte man normalerweise keine Standardfunktion hernehmen, die einem fast alles abnehmen, sondern das Ganze selber implementieren.

Jedenfalls hier einmal der Code
C++:
#include<limits.h>

long int str_to_long(char in[])
{
    long int erg=0;
    if((*in)=='-')return LONG_MIN;
    while((*in)!='\0')
    {
        if( (*in)<'0'|| (*in)>'9' ) return LONG_MAX;
        if(erg>( erg*10-'0'+(*in) )) return LONG_MAX;
        erg=erg*10-'0'+(*in);
        in++;
    }
    return erg;
}
 
Zuletzt bearbeitet:
Habs ausgebessert, zusammen mit dem ganzen Satz (der mir sowieso nicht gefallen hat).

Und die Überlaufprüfung ist das Zweite if im while.

Gruß
 
Weitermachen? Gar nicht, denn die Funktion läuft so wie ich sie gepostet habe.
Oder doch, die Aufgabenstellung verlangt ja noch ein main, in dem die Funktion getestet wird

Wie du das "Testen" genau machst, bleibt dann wohl dir überlassen.

Du könntest zB immer einen String von der Tastatur einlesen, durch die Funktion schicken, am Ende das Ergebnis am Bildschirm ausgeben und dann das Ganze wieder von vorne.

zB so:
C++:
#include<stdio.h>

int main()
{
    char c[1024];
    while(1)
    {
        gets(c);
        printf("%d\n", str_to_long(c) );
    }
}

@Matthias Reitinger: Ist natürlich auch eine Möglichkeit.
Und weils grad so lustig ist, gibts die Variante auch gleich...
 
Hier die andere Variante (falls das mit dem Minus anders gemeint war):
C++:
#include<limits.h>

long int str_to_long(char in[])
{
    long int erg=0, test;
    bool negativ=0;
    if((*in)=='-')
    {
        negativ=true;
        in++;
    }
    while((*in)!='\0')
    {
        if( (*in)<'0'|| (*in)>'9' ) return ((negativ)?LONG_MIN:LONG_MAX);
        test=erg*10-'0'+(*in);
        if(erg>test) return ((negativ)?LONG_MIN:LONG_MAX);
        erg=test;
        in++;
    }
    return ((negativ)?(-erg):erg);
}

edit: 1300 :D
 
Zurück