Bibliotheksfunktion atoi?



  • 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.



  • Also Leute,

    Ich hab jetzt folgenden Code:

    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;
    }
    

    Diese Funktion geht jetzt schon mal soweit, auch wenn man führende Leerzeichen eingibt. Für Leerzeichen die nach der Zahl kommen geht sie dann schon leider nicht mehr...



  • bandchef schrieb:

    ... Für Leerzeichen die nach der Zahl kommen geht sie dann schon leider nicht mehr...

    Dann ist die Zahl ja auch vorbei und du bist fertig.

    Du kannst auch statt

    while(string[i] != '\0' && string[i] >= '0' && string[i] <= '9')
    

    folgendes

    while(isdigit(string[i]) != 0)
    

    schreiben, da alles andere als Zahlen dich nicht mehr interresieren.
    ('\0' ist kein digit, also bricht die Schleife da auch ab)



  • Der Ansatz ist ja schonmal ok, und offensichtlich hast Du mit Pointern noch nie gearbeitet, sehe ich das richtig? Also das ist eigentlich ganz einfach und lohnt wirklich! Lies dir am besten mal etwas dazu durch und probiers aus, das ist nicht schwer 😉 (Auch wenn es am Anfang vielleicht so scheint)

    Und zu deiner Schleife:
    Du machst immer noch Dinge die nicht notwändig sind!
    Man kann (siehe vorher geposteter Code) auch immer erst "links shiften" (also * 10 im Dezimalsystem) wenn man eine neue Zahl findet. Also:

    while ..
    {
      zahl = zahl * 10; //oder auch zahl *= 10;
      zahl = zahl + (string[i] - '0'); // oder auch zahl += string[i] - '0';
      i = i + 1; // oder auch i += 1; oder ++i; oder i++;
    }
    

    Würde also zB. folgendes passieren:
    -in string steht "123"
    -zahl ist 0

    1. Durchlauf
    0 * 10 = 0 // zahl bleibt 0
    0 + 1 = 1 // zahl ist jetzt 1

    2. Durchlauf
    1 * 10 = 10
    10 + 2 = 12

    3. Durchlauf
    12 * 10 = 120
    120 + 3 = 123

    fertig 😃

    Desweiteren wird die Variable "sign" nirgendwo verwendet.
    Sieh dir noch mal den anderen code an und komplettier das 😉



  • Hm, wenn man mal eine Nacht drüber geschlafen hat, dann gehts gleich viel besser 🙂 Hier mal mein neuer Code. So wie es schein funktioniert dieser jetzt auch für alle Möglichkeiten, sprich mit/ohne Vorzeichen und/oder mit/ohne führende/folgende Leerzeichen. Pointer glaub ich ab ich soweit auch korrekt angewendet. Eine Frage hab ich dann noch: Dieses ++string, hab ich mir aus euren Code-Beispielen abgeguckt. Dieses Teil schaltet ja die Stellen im String weiter. Ich denke, das ist soviel wie mein vorheriges i=i+1 wie ich noch keine Pointer verwendet habe. Was aber verbirgt sich dahinter? Wenn ich ++i (Prä/Postfix) schreibe, dann bedeutet das ja i=i+1. Was ist dann aber das äquivalten zu ++string? string = string + 1; geht nicht hab ich ausprobiert, genausowenig geht *string = *string + 1;. Könnt ihr mich da aufklären?

    #include<stdio.h>
    #include<stdlib.h>
    #include<ctype.h>
    #include<string.h>
    
    char* string_eingeben(char *string)
    {
    	int i = 0;
    	char zeichen;
    	zeichen = getchar();
    
    	while(zeichen != '\n')
    	{
    		*string = zeichen;
    		zeichen = getchar();
    		++string;
    	}
    	*string = '\0';
    
    	return string;
    }
    
    int my_atoi(char *string)
    {
    	int i = 0, zahl = 0, sign = 1;
    
    	while(*string == ' ' || *string == '\t')
    	{
    		++string;
    	}
    
    	if(*string == '-')
    	{
    		sign = -1;
    		++string;
    	}
    
    	while(*string != '\0' && *string >= '0' && *string <= '9')
    	{
    		zahl = zahl * 10;
    		zahl = zahl + (*string - '0');
    		++string;
    	}
    	zahl = zahl * sign;
    	return zahl;
    }
    
    int main()
    {
    	char string[100];
    	int zahl;
    
    	string_eingeben(string);
    	zahl = my_atoi(string);
    
    	printf("my_atoi: int-Zahl = %i\n", zahl);
    
    return 0;
    }
    

    EDIT: Oh mann! Bis vor 5 min. hat der obige Code noch funktioniert. Jetzt hab ich irgendwas verändert und jetzt geht nix mehr! Und ihr könn sicher schon vermuten, dass ich es nicht weiß was fuckt...

    EDIT2: Hab den Fehler gefunden. Ich hab sign dummerweise mit 0 initialisiert! Dass, das nix wird war klar... Jetzt geht der Code jedenfalls... Auf zur nächsten Aufgabe... 🙂



  • Wo hast du denn string = string + 1; bzw *string = *string + 1; ausprobiert?

    Wie wärs noch mit einem + als Vorzeichen?



  • Code mit zusätzlichem + als Vorzeichen:

    #include<stdio.h>
    #include<stdlib.h>
    #include<ctype.h>
    #include<string.h>
    
    char* string_eingeben(char *string)
    {
        int i = 0;
        char zeichen;
        zeichen = getchar();
    
        while(zeichen != '\n')
        {
            *string = zeichen;
            zeichen = getchar();
            ++string;
        }
        *string = '\0';
    
        return string;
    }
    
    int my_atoi(char *string)
    {
        int i = 0, zahl = 0, sign = 1;
    
        while(*string == ' ' || *string == '\t')
        {
            ++string;
        }
    
        if(*string == '-')
        {
            sign = -1;
            ++string;
        }
    
    	if((*string == ' ') || (*string == '+'))
    	{
    		sign = +1;
            ++string;
    	}
    
        while(*string != '\0' && *string >= '0' && *string <= '9')
        {
            zahl = zahl * 10;
            zahl = zahl + (*string - '0');
            ++string;
        }
        zahl = zahl * sign;
        return zahl;
    }
    
    int main()
    {
        char string[100];
        int zahl;
    
        string_eingeben(string);
        zahl = my_atoi(string);
    
        printf("my_atoi: int-Zahl = %i\n", zahl);
    
    return 0;
    }
    

    Wie geht das jetzt mit weiterzählen der Elemente bei einem als pointer übergegebenen String?



  • bandchef schrieb:

    Code mit zusätzlichem + als Vorzeichen:

    if((*string == ' ') || (*string == '+'))
    	{
    		sign = +1;
            ++string;
    	}
    

    Das geht so nicht. Die Leerzeichen hast du vorher schon alle aussortiert. Dein Zeichen kann entweder nur eine Zahl oder ein Plus sein. Bei einer Zahl darfst du den Zeiger dann auch nicht erhöhen, weil du sie sonst aus der Konvertierung nimmst.

    bandchef schrieb:

    Wie geht das jetzt mit weiterzählen der Elemente bei einem als pointer übergegebenen String?

    Was willst du machen? Ein inkrementieren eines Zeiger zeigt immer auf das nächste Element. Start und Ende des Speicherbereiches musst du dir dabei selber merken. Der Inhalt eines Strings ist ab dem abschließenden Nullzeichen ungültig.



  • Das ++string entspricht dem string = string + 1;

    Das *string = *string + 1; entspricht string[0] += 1;

    Du hast nur geschrieben geht nicht. Wie hat sich das geäußert?

    Du kannst das nur bei *char string machen, aber nicht bei char string[]

    Bei deinem my_atoi geht auch -+4711 (+-4711 geht nicht)



  • Wegen der Frage mit den Pointern..
    http://www.peacesoftware.de/ckurs12.html
    Find ich ganz nett erklärt 😉



  • Bei deinem my_atoi geht auch -+4711 (+-4711 geht nicht)

    Das +-4711 geht jetzt jedenfalls.

    Das geht so nicht. Die Leerzeichen hast du vorher schon alle aussortiert. Dein Zeichen kann entweder nur eine Zahl oder ein Plus sein. Bei einer Zahl darfst du den Zeiger dann auch nicht erhöhen, weil du sie sonst aus der Konvertierung nimmst.

    Ich denke das Problem ist jetzt soweit auch gelöst. Schaut euch den Code doch nochmal kurz durch. Ich meine, dass der jetzt soweit funktionieren sollte!

    Die Erklärungskurs zu den Pointern war in der Tat gut erklärt. Hab ich mir aufmerksam durchgelesen. Danke!

    #include<stdio.h>
    
    char* string_eingeben(char *string)
    {
    	int i = 0;
    	char zeichen;
    	zeichen = getchar();
    
    	while(zeichen != '\n')
    	{
    		*string = zeichen;
    		zeichen = getchar();
    		++string;
    	}
    	*string = '\0';
    
    	return string;
    }
    
    int my_atoi(char *string)
    {
    	int i = 0, zahl = 0, sign = 1;
    
    	while(*string == ' ' || *string == '\t')
    	{
    		++string;
    	}
    
        if((*string == '+') || (*string == '-'))
    	{
    		sign = -1;
    		++string;
    	}
    
        if((*string == '+') || (*string == '-'))
    	{
    		sign = -1;
    		++string;
    	}
    
    	while(*string != '\0' && *string >= '0' && *string <= '9')
    	{
    		zahl = zahl * 10;
    		zahl = zahl + (*string - '0');
    		++string;
    	}
    	zahl = zahl * sign;
    	return zahl;
    }
    
    int main()
    {
    	char string[100];
    	int zahl;
    
    	string_eingeben(string);
    	zahl = my_atoi(string);
    
    	printf("my_atoi: int-Zahl = %i\n", zahl);
    
    system("pause");
    return 0;
    }
    

  • Mod

    Und was kommt bei +1 heraus?

    Außerdem zeigt vieles an deinem Code, dass du ihn nicht wirklich verstanden hast, sondern bloß ein paar Codefetzen aus diesem Thread aneinandergehängt hast bis es funktioniert hat. Dazu folgende weise Worte:

    c.rackwitz schrieb:

    Wenn du selber Code schreibst, musst du ihn auch verstehen. Code ist kein Haufen von wahllos zusammengeschmissenen Buchstaben und Zeichen, Code ist Logik pur. Du musst genau wissen, warum du wo und welches Zeichen setzt.

    Nimm dir das mal zu Herzen - du hast es dringend nötig.



  • Und was kommt bei +1 heraus?

    Jetzt geht auch die +1.

    #include<stdio.h>
    
    char* string_eingeben(char *string)
    {
    	int i = 0;
    	char zeichen;
    	zeichen = getchar();
    
    	while(zeichen != '\n')
    	{
    		*string = zeichen;
    		zeichen = getchar();
    		++string;
    	}
    	*string = '\0';
    
    	return string;
    }
    
    int my_atoi(char *string)
    {
    	int i = 0, zahl = 0, sign = 1;
    
    	while(*string == ' ' || *string == '\t')
    	{
    		++string;
    	}
    
        if(*string == '+')
    	{
            sign = 1;
            ++string;
            if(*string == '-')
            {
                sign = -1;
    		    ++string;
            }
    	}
    
        if(*string == '-')
    	{
            sign = -1;
            ++string;
            if(*string == '+')
            {
                sign = -1;
    		    ++string;
            }
    	}
    
    	while(*string != '\0' && *string >= '0' && *string <= '9')
    	{
    		zahl = zahl * 10;
    		zahl = zahl + (*string - '0');
    		++string;
    	}
    	zahl = zahl * sign;
    	return zahl;
    }
    
    int main()
    {
    	char string[100];
    	int zahl;
    
    	string_eingeben(string);
    	zahl = my_atoi(string);
    
    	printf("my_atoi: int-Zahl = %i\n", zahl);
    
    system("pause");
    return 0;
    }
    

Anmelden zum Antworten