Bibliotheksfunktion atoi?



  • Hat ja erstmal geklappt.

    Nur soll dein atoi erkennen ob es eine korrekte Zahl bekommt, nicht die Eingabefunktion.

    Du kannst isdigit() aus <ctype.h> benutzen.
    Du kannst statt 48 besser '0' schreiben.

    int my_atoi(zeichen[])
    zahl = 0
    i = 0
    solange zeichen[i] eine Zahl ist tue
      zahl = zahl * 10
      zahl = zahl + zeichen - '0'
      i++
    
    return zahl
    

    Und Int-konstanten können auch 0xff oder 077 sein 😮

    Denke auch an führende Leerzeichen mit isspace()



  • Tja Leute, da hab ich wohl dann wieder mal gezeigt, dass ich nich viel Ahnung von C habe. Aberg egal, es ist noch kein Meister vom Himmel gefallen. Ich hab hiermit mal versucht, DirkB's Vorschlag umzusetzen. Leider funktionierts noch nicht ganz wie ich es erwartet habe:

    int my_atoi(char string[])
    {
    	int i = 0, zahl = 1, zeichen;
    	while(((isdigit(string[i])) || (isxdigit(string[i]))) == 1)
    	{
    		zahl = zahl * 10;
    		zeichen = string[i];
    		zahl = zahl + zeichen - '0';
    		i = i + 1;
    	}
    	return zahl;
    }
    

    Wo ich mir als ertes nicht sicher bin ob man das so machen darf, ist das isdigit(). In meiner Literatur heißt es, dass isdigit() einen VON NULL VERSCHIEDENEN Wert zurückliefert, wenn das Argument erfüllt ist. Das heißt Abfrage auf 1 kann also schon falsch sein, oder? Wie aber soll ich es denn dann machen?


  • Mod

    bandchef schrieb:

    Tja Leute, da hab ich wohl dann wieder mal gezeigt, dass ich nich viel Ahnung von C habe. Aberg egal, es ist noch kein Meister vom Himmel gefallen. Ich hab hiermit mal versucht, DirkB's Vorschlag umzusetzen. Leider funktionierts noch nicht ganz wie ich es erwartet habe:

    Guck dir DirkB's Vorschlag nochmal an, bemerke die kleinen aber wichtigen Unterschiede zu deinem Code.

    Wo ich mir als ertes nicht sicher bin ob man das so machen darf, ist das isdigit(). In meiner Literatur heißt es, dass isdigit() einen VON NULL VERSCHIEDENEN Wert zurückliefert, wenn das Argument erfüllt ist. Das heißt Abfrage auf 1 kann also schon falsch sein, oder? Wie aber soll ich es denn dann machen?

    Indem du auf ungleich 0 prüfst?

    while(((isdigit(string[i])) || (isxdigit(string[i]))) == 1)
    

    Was soll denn das? Beschreib mal in Worten, was dies machen soll.



  • So, hier nochmal mein neuer Code:

    int my_atoi(char string[])
    {
    	int i = 0, j = 0, potenz, zahl = 0, zaehler, zeichen;
    	while(isdigit(string[i]) != 0)
    	{
    	potenz = 1;
    	zaehler = strlen(string);
            for(j=i; j<(zaehler-1); j=j+1)
            {
               potenz = potenz * 10;
            } 
    		zeichen = string[i];
    		zahl = zahl + (potenz * (zeichen - '0'));
    		i = i + 1;
    	}
    	return zahl;
    }
    
    while(((isdigit(string[i])) || (isxdigit(string[i]))) == 1)
    

    Ich wollte damit bezwecken, dass er mir auf hexzahlen prüft, aber das ist ja totaler schwachsinn, da die potenz mit der ich später multiplizieren muss damit ich auf dezimalzahlen komme, dann nicht mehr überein stimmt. Der Code oben berechnet mir jetzt zumindestens schon mal die korrekten dezimalzahlen, aber leider immer noch ohne führende whitespaces...

    int my_atoi(zeichen[])
    zahl = 0
    i = 0
    solange zeichen[i] eine Zahl ist tue
      zahl = zahl * 10
      zahl = zahl + zeichen - '0'
      i++
    
    return zahl
    

    DirkB's Vorschlag steht oben. Er schreibt "solange" string[i] eine Zahl ist tue:.

    Wie soll ich das aber jetz in einer while-schleife formulieren, falls leerzeichen drin sind? Da sind ja z.B. die ersten Stelle zu überspringen da eben Leerzeichen... Das wär ja dann sowas wie eine if-Abfrage, oder? Ich kann aber doch keine if-Abfrage in den Kopf einer while-schleife schreiben, wie soll denn das gehen?


  • Mod

    bandchef schrieb:

    Wie soll ich das aber jetz in einer while-schleife formulieren, falls leerzeichen drin sind? Da sind ja z.B. die ersten Stelle zu überspringen da eben Leerzeichen... Das wär ja dann sowas wie eine if-Abfrage, oder? Ich kann aber doch keine if-Abfrage in den Kopf einer while-schleife schreiben, wie soll denn das gehen?

    😕 Was ist denn wohl das was im Kopf der while-Schleife steht?

    Hier mal ein bisschen Code für den Anfang. Den Rest überlasse ich aber bewusst dir. Lass erstmal solchen Kram wie Hexzahlen, Überläufe und ähnliches außen vor. Bring erst einmal die grundlegenden Sachen zum Laufen!

    int my_atoi ( const char * string )
    {
      // Discard leading whitespace
      while(isspace(*string)) ++string;
    
      // Check sign
      int sign=1;
      if (*string=='-') 
        {
          sign=-1;
          ++string;
        }
    
      // Hier dein Code
    }
    


  • Lasse die Standardbbliotheksfunktionen für dich arbeiten:

    int my_atoi(char * astring)
    {
        int i = 0, j = 0, potenz, zahl = 0, zaehler, zeichen;
        char *string=malloc(strlen(astring)+1);
        sscanf(astring,"%s",string); /* das hier entfernt führende+endende Leerzeichen und sonstige "Whitespaces" */
        while(isdigit(string[i]) != 0)
        {
        potenz = 1;
        zaehler = strlen(string);
            for(j=i; j<(zaehler-1); j=j+1)
            {
               potenz = potenz * 10;
            }
            zeichen = string[i];
            zahl = zahl + (potenz * (zeichen - '0'));
            i = i + 1;
        }
        free(string);
        return zahl;
    }
    


  • Ach noch was, hatten wir schon beim letzten mal:

    char* string_eingeben(char string[]) MUSS wissen wie viel Platz in string ist. Sonst kannst du deinen gesamten Speicher überschreiben.
    (Kann man eigentlich etwas rot blinkend hervorheben?)

    Diese Fehler sind mit der Grund dass Viren und Würmer ein System befallen können. Gewöhn dir das jetzt an.



  • Wie sage ich das ihm wieviel Platz der String hat?


  • Mod

    Wutz schrieb:

    Lasse die Standardbbliotheksfunktionen für dich arbeiten:

    Dann kannst du auch gleich strtol benutzen. Das macht es dann auch einfacher, solche Sachen wie Überlaufe abzufangen (denn atoi muss laut Standard dann INT_MAX bzw. INT_MIN zurückgeben). Dies ist übrigens wirklich, wie atoi oft implementiert wird (zumindest laut Google Code Search).



  • int my_atoi(char * astring)
    {
        int i = 0, j = 0, potenz, zahl = 0, zaehler, zeichen;
        char *string=malloc(strlen(astring)+1);
        sscanf(astring,"%s",string); /* das hier entfernt führende+endende Leerzeichen und sonstige "Whitespaces" */
        while(isdigit(string[i]) != 0)
        {
        potenz = 1;
        zaehler = strlen(string);
            for(j=i; j<(zaehler-1); j=j+1)
            {
               potenz = potenz * 10;
            }
            zeichen = string[i];
            zahl = zahl + (potenz * (zeichen - '0'));
            i = i + 1;
        }
        free(string);
        return zahl;
    }
    

    Warum ist da jetzt eigentlich ein Pointer oben in der Deklarationsliste der funktion? Versteh ich nicht...



  • Vielleicht hilfreich:
    http://de.wikipedia.org/wiki/Zeiger_(Informatik)#Zeigeroperationen

    Und dein Schleifenkopf könnte zB. so aussehen:

    while (*string != '\0' && *string >= '0' && *string <= '9')
    


  • Mein Code bisher:

    int my_atoi(char string[])
    {
    	int i = 0, j = 0, potenz, sign, zahl = 0, zaehler, zeichen;
    
    	while(isspace(string[i]) != 0)
    	{
    		i = i + 1;
    	}
    
    	while(isdigit(string[i]) != 0)
    	{
    		potenz = 1;
    		zaehler = strlen(string);
            for(j=i; j<(zaehler-1); j=j+1)
            {
                potenz = potenz * 10;
            } 
    		zeichen = string[i];
    		zahl = zahl + (potenz * (zeichen - '0'));
    		i = i + 1;
    	}
    	return zahl;
    }
    

    Die erste while-Schleife prüft mir jetzt auf die führenden Leerzeichen. Jetzt muss ich halt die Leerzeichen irgendwie wegbringen und meine Zahlenreihenfolge irgendwie verschieben. Ihr wisst was ich meine, oder? Wie aber mach ich das jetzt?



  • Warum ist da jetzt eigentlich ein Pointer oben in der Deklarationsliste der funktion? Versteh ich nicht...

    Weil es unschön (oh Gott.. hoffentlich trete ich jetzt niemandem damit auf den Fuß ;)) ist arrays zu übergeben. Normalerweise übergibt man bei zB. strings einfach einen Pointer auf sein erstes Element.



  • Guck dir das mal an, wenn Du was nicht verstehst frag 😉
    (Ach ja, auf INT_MAX und INT_MIN wird hier keine rücksicht genommen)

    #include <stdio.h>
    
    int my_atoi(char *string)
    {
      int val = 0, sign = 1;
      while (*string == ' ' || *string == '\t') // leerzeichen und tabs weg 
        ++string; // pointer wird um ein element verschoben
      if (*string == '-') // signed ?
      {
        sign = -1;
        ++string;
      }
      while (*string != '\0' && *string >= '0' && *string <= '9')
      {
        val = val * 10; // zahl wird im dezimalsystem "geshiftet"
        val += *string - '0'; // zB. '1' hat immer den wert von '0' + 1
        ++string;
      }
      return val * sign; // *sign sollte klar sein
    }
    
    int main()
    {
      char buffer[0x100];
    
      fgets(buffer, sizeof(buffer), stdin);
      printf("%i", my_atoi(buffer));
    
      return 0;
    }
    


  • Hm, Leute!

    Kann mir vielleicht jemand stückchenweise durch mein Problem helfen?

    Mein Code lautet jetzt so:

    int my_atoi(char string[])
    {
    	int i = 0, j = 0, potenz, sign, zahl = 0, zaehler, zeichen;
    
    	while(isspace(string[i]) != 0)
    	{
    		i = i + 1;
    	}
    
    	while(string[i] != '\0' && string[i] >= '0' && string[i] <= '9')
    	{
    		potenz = 1;
    		zaehler = strlen(string);
            for(j=i; j<(zaehler-1); j=j+1)
            {
                potenz = potenz * 10;
            } 
    		zeichen = string[i];
    		zahl = zahl + (potenz * (zeichen - '0'));
    		i = i + 1;
    	}
    	return zahl;
    }
    

    Ich weiß da jetzt echt nicht mehr wirklich weiter...


  • Mod

    bandchef schrieb:

    Jetzt muss ich halt die Leerzeichen irgendwie wegbringen und meine Zahlenreihenfolge irgendwie verschieben. Ihr wisst was ich meine, oder? Wie aber mach ich das jetzt?

    Warum? Du weißt doch schon, von wo aus deine Zahl losgeht. Was für einen Unterschied macht es, wo das ist?



  • bandchef (238 Beiträge) schrieb:

    Kann mir vielleicht jemand stückchenweise durch mein Problem helfen?

    Machst du gelegentlich auch mal was selber?



  • Man sieht doch, dass er es versucht hat. Dann soll er lieber fragen, als dass er einfach rät wie es funktioniert.



  • bandchef schrieb:

    Hm, Leute!

    Kann mir vielleicht jemand stückchenweise durch mein Problem helfen?

    ..

    Ich weiß da jetzt echt nicht mehr wirklich weiter...

    Also hättest Du dir alle hier geposteten Codes gründlich durchgelesen sollte das ganze wirklich kein Problem mehr darstellen.. ich meine.. ich hab dir die Aufgabe sozusagen komplett gelöst? ^^

    Lies dir den Code einfach mal genau durch, Schritt für Schritt, und versuche nachzuvollziehen was genau passiert. Wenn dann eine konkrete Frage kommt können wir die auch beantworten 😉



  • bandchef schrieb:

    Wie sage ich das ihm wieviel Platz der String hat?

    Du hattest da ein Problem mit Array als return-Wert! http://www.c-plusplus.net/forum/279679-20
    Da hatte ich was von EVA gesagt. Das hast du zumindest gelesen.
    Aber da waren auch noch ein Codebeispiele zu diesem Thema: einmal mit fgets und einmal deine modifizierte Eingabefunktion.


Anmelden zum Antworten