Autor Thema: char nach int umwandeln  (Gelesen 14479 mal)

Cool-Andy

  • Gast
Gespeichert
« am: 17. October 2009, 19:43 »
Hallo nochmal,
ich hätte da nochmal ne wahrscheinlich ziemlich dumme Anfängerfrage:
wie kann man mit möglichst Standard-C-Funktionen einen char-String in eine int-Zahl umwandeln?

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 17. October 2009, 19:59 »
Hallo,


wenn Du ein char[] mit z.B. "123" meinst dann ist 'sscanf()' Dein Freund.


Grüße
Erik
Reality is that which, when you stop believing in it, doesn't go away.

Cool-Andy

  • Gast
Gespeichert
« Antwort #2 am: 17. October 2009, 20:03 »
Und wie implentier ich die in mein OS?  :?

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 17. October 2009, 20:11 »
Hallo,


"Standard-C-Funktionen" sind in der Standard-C-Bibliothek. Wenn Du die nicht in Deinen Kernel mit reinlinken möchtest, was auch nicht empfehlenswert ist, dann schau Dich mal beim Linux-Kernel um die haben eine abgespeckte Fassung (sscanf unterstützt z.B. keine Gleitkommazahlen) aus der Du bestimmt alles benötigte herrausfiletieren kannst.


Grüße
Erik
Reality is that which, when you stop believing in it, doesn't go away.

Tobiking

  • Beiträge: 24
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 17. October 2009, 20:17 »
atoi() währe wohl die direkte Funktion wenn du die hättest.

Und wie implentier ich die in mein OS?  :?
Ich würde Zeichen für Zeichen einlesen, die entsprechende Ziffer finden und dann die Ziffern zusammensetzen. So nach dem Motto "1234" ist 1*1000+2*100+3*10+4*1.

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 17. October 2009, 20:21 »
Von sscanf würde ich abraten solange man sich solche Fragen stellt.

Einfacher ist atoi:

1. Setze Variable x auf 0
2. Zeichen einlesen
3. Zeichen von ASCII in den Wert der Stelle umwandeln
4. x <- x * 10 + Wert aus 3.
5. Wenn noch nicht am Ende -> gehe zu 2.
6. Gib x zurück.
Dieser Text wird unter jedem Beitrag angezeigt.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 17. October 2009, 20:23 »
strtol() ist noch besser. Muss aber auch erst implementiert werden. ;)

Der Ansatz von Tobiking dürfte dich schnell zum Ziel führen. Ein einzelnes Zeichen (von dem du weißt, dass es eine Ziffer ist) wandelst du am geschicktesten mit c - '0' in eine Zahl um.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

Cool-Andy

  • Gast
Gespeichert
« Antwort #7 am: 17. October 2009, 20:58 »
Vielen Danke für die Antworten,
aber die von PorkChicken hab ich noch nich so wirklich verstanden, könntest du mal ein Stück Code posten (ich denke, Pseudocode würde reichen).


Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 17. October 2009, 21:23 »
Das war ja im prinzip Pseudocode ;)

Aber hier mal als ungetestes C-Schnipsel, und in den Kommentaren die Bezüge zum Pseudocode:
int atoi(const char *str)
{
    int x = 0; // der Wert // (1.)
    int d; // eine Ziffer

    while (*str) {
        d = *str - '0'; // (2.) + (3.)
        x = x * 10 + d; // (4.)
        str++;
    }

    return x; // (6.)
}
Der Punkt (5.) ist schwer in diesem Code unterzubringen, aber entspricht wohl am ehesten der while-Schleife.

Da fehlt jetzt natürlich die Verarbeitung von negativen Zahlen ;)
Dieser Text wird unter jedem Beitrag angezeigt.

Cool-Andy

  • Gast
Gespeichert
« Antwort #9 am: 17. October 2009, 22:11 »
OK,
vielen Dank. Könntest du mir auch noch sagen, wie man wieder von int nach char umwandelt. (Bitte nicht wundern, hab bis jetzt noch nie ints und chars umwandeln müssen.)

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #10 am: 17. October 2009, 22:17 »
Du teilst die Zahl immer wieder durch 10, der Rest gibt jeweils genau die letzte Ziffer. Folgender Pseudocode gibt die Zahl also rückwärts aus, das Umdrehen überlasse ich dir. ;)

while n > 0 do
  putc('0' + (n % 10));
  n := n / 10;
od
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

Cool-Andy

  • Gast
Gespeichert
« Antwort #11 am: 17. October 2009, 22:22 »
OK, vielen Dank, werd ich gleich mal ausprobieren.

Cool-Andy

  • Gast
Gespeichert
« Antwort #12 am: 18. October 2009, 08:16 »
Ich cheks net, entweder bei mir kommt nur Müll raus (Zeichen wie sowas: █), oder es kommt gar nix.
Könntest du bitte mal einen C-Code posten?
Ich denke, es wäre eine große Hilfe für mich.  :mrgreen:

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #13 am: 18. October 2009, 09:00 »
Hallo,


int itostr(char* const str, int zahl)
{
    if (zahl == 0)
      { *str = '0'; return 1; } //bei 0 nur "0" zurückgeben

    int i = 0; //String-Länge

    while (zahl > 0) { //Loop solange bis Zahl 0 ist
        const int rest = zahl % 10;
        zahl = zahl / 10;
        str[i++] = ((char)rest) + '0';
    }

    return i; //Länge des Strings zurückgeben
}
Da fehlt auch wieder die Behandlung negativer Zahlen aber ansonsten sollte das funktionieren.


Grüße
Erik
Reality is that which, when you stop believing in it, doesn't go away.

Cool-Andy

  • Gast
Gespeichert
« Antwort #14 am: 18. October 2009, 10:18 »
Ok,
hab die Funktion übernommen, aber irgendwie funzts net.
Ich poste mal meinen Code:
string.c:
// ...
int atoi(const char *str)
{
    int x = 0; // der Wert // (1.)
    int d; // eine Ziffer

    while (*str) {
        d = *str - '0'; // (2.) + (3.)
        x = x * 10 + d; // (4.)
        str++;
    }

    return x; // (6.)
}

int itoa(int zahl)
{
    if (zahl == 0)
    {
key[0] = '0';
key[1] = '\0';
return 1;
} //bei 0 nur "0" zurückgeben

    int i = 0; //String-Länge

    while (zahl > 0) { //Loop solange bis Zahl 0 ist
        const int rest = zahl % 10;
        zahl = zahl / 10;
        key[i++] = ((char)rest) + '0';
    }

key[i] = '\0';

    return i; //Länge des Strings zurückgeben
}

und main.c:
// ...
i = 0;
printf ("\n");
printf ("1: ");
scanf ();
i = atoi(key);
itoa(i);
printf (key);
printf ("\n");
// ...

Wobei "key" eine 80-Zeichen lange char-Variable ist, und für den Austausch von Zeichen gedacht ist (und auch Zeichen von der Tastatur entgegen nimmt).

Erkennt ihr den Fehler? Ich bin echt ratlos!  :?

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #15 am: 18. October 2009, 10:31 »
Hallo,


Zitat
aber irgendwie funzts net
Kannst Du das etwas konkreter ausdrücken?
Baue den Code einfach mal in ein normales Programm auf deinem Entwicklungsrechner ein und nimm einen Debugger, vielleicht findest Du dann den Fehler.


Grüße
Erik
Reality is that which, when you stop believing in it, doesn't go away.

Cool-Andy

  • Gast
Gespeichert
« Antwort #16 am: 18. October 2009, 10:49 »
Kannst Du das etwas konkreter ausdrücken?
Wenn eine Zahl unterhalb 4 eingegeben wird, erscheint überhaupt keine Ausgabe. Bei jeder anderen Zahl erscheint eine wirre Zahlenfolge.

Baue den Code einfach mal in ein normales Programm auf deinem Entwicklungsrechner ein und nimm einen Debugger, vielleicht findest Du dann den Fehler.
Ok, hab ich gemacht. Ich hab die Funktionen in ein Windows-Programm gepackt und siehe da funktionierts, was mich eigentlich noch ratloser macht!

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #17 am: 18. October 2009, 12:50 »
Hallo,


Zitat
Wenn eine Zahl unterhalb 4 eingegeben wird, erscheint überhaupt keine Ausgabe. Bei jeder anderen Zahl erscheint eine wirre Zahlenfolge.
Kann es vielleicht sein das etwas mit der Parameterübergabe beim Funktionsaufruf nicht passt? Ist nur so ne Idee.

Zitat
... was mich eigentlich noch ratloser macht!
Das ist sehr merkwürdig. Ich schätze da wirst Du nicht drumrum kommen das ganze in kleine Häppchen zu zerlegen und alles einzeln testen bis Du die schuldige Code-Stelle gefunden hast. Hast Du schon mal den Debugger von Bochs probiert? Als erstes solltest Du IMHO probieren das Int-2-String klappt, dafür nimmst Du am besten hartcodierte Int-Werte.

Probiere mal d = *str - '0';gegend = ((int)(*strr)) & 0x0F;undkey[i++] = ((char)rest) + '0';gegenkey[i++] = (char)(rest - 0x30);zu ersetzen, eventuell hast Du ein Problem mit dem Zeichensatz.
Ansonsten solltest Du eine Fehlermeldung einbauen wenn 'rest' nicht im Wertebereich 0...9 ist. So in der Art :if ( (rest < 0) || (rest > 9) ) { printf("Error!!"); }
Viel mehr fällt mir momentan auch nicht ein.


Viel Spaß :wink:
Erik
Reality is that which, when you stop believing in it, doesn't go away.

Cool-Andy

  • Gast
Gespeichert
« Antwort #18 am: 18. October 2009, 17:29 »
Hmm, ich find den Fehler nicht!  :-(
Ich hab mich entschieden, die Funktion aufzuschieben, um an meinem OS weiterzukommen, vielleicht findet ja einer von euch noch den Fehler.
Vielen Dank jeden Falls.

Cjreek

  • Beiträge: 104
    • Profil anzeigen
Gespeichert
« Antwort #19 am: 22. October 2009, 21:15 »
Naja an so etwas sollte man eigentlich nicht verzweifeln (müssen).

Zuerst den kompletten Code den du für diese Funktion geschrieben hast wegwerfen, damit du nicht beeinflusst wirst. Du fängst jetzt ganz von vorne an.

Guck mal. Nehmen wir mal die Zahl 12345.

durch 10 teilen:
1234 R 5
durch 10 teilen
123 R 4
durch 10 teilen
12 R 3
durch 10 teilen
1 R 2
durch 10 teilen
0 R 1

*) R = Rest

Wie du siehst ergeben die unterstrichenen Zahlen von unten nach oben gelesen deine ursprüngliche Zahl.

Was haben wir also gemacht?

1) Wir haben die Zahl genommen die wir umwandeln wollten und solange durch 10 geteilt bis das Ergebnis 0 war.
2) Wir haben jeweils den Rest jeder Division genommen und ihn in einen Char umgewandelt.

Wie macht man das? Nunja..

Die "0" hat den Ascii-Code 0x30
die "1" 0x31, die "2" 0x32 usw.

Wir können also einfach 0x30+R rechnen und haben dann den Ascii-Code der aktuellen Ziffer (R = der Rest der aktuellen Division)

den AsciiCode in einen Char umwandeln kannst du durch

(char)code
also in unserem Fall:

(char)(0x30+R)
3) Von hinten nach vorne gelesen ergeben diese Chars dann die gewünschte Zahl als String.

Wenn du dir das mal so durchgehst und evtl auch mal auf nem Blatt ausprobierst, dann schreibt sich der Code fast von alleine ;)

Lg
Cjreek
"Programmers talk about software development on weekends, vacations, and over meals not because they lack imagination,
but because their imagination reveals worlds that others cannot see."

 

Einloggen