Forum: Compiler & IDEs Funktion, die Zahl aus Zeichen zusammenbastelt


von Martin S. (tungl)


Lesenswert?

Hallo,

ich habe eine Funktion geschrieben, der man die Anzahl der zu 
erwartenden Zeichen/Ziffern, die ueber UART reinkommen, mit gibt und die 
so lang darauf wartet, bis genug Zeichen eingetroffen sind und danach 
dann eine Zahl daraus machen soll.

Das Ganze sieht so aus:
1
int expectNumber(int digits) {
2
    char input;
3
    int r = 0;
4
    int i;
5
    
6
    for (i=1; i<=digits; i++)
7
    {
8
        input = UARTReceive();
9
        while (!characterIsNumber(input)) {
10
            input = UARTReceive();
11
        }
12
        
13
        int n = atoi(&input);
14
  
15
        r += (10^(digits-i)) * n;
16
        
17
        char buf[50];
18
        sprintf(buf, "\n\n Char is: %c, n is: %d, r is now: %d\n", input,n,r);
19
        UARTPuts(buf);
20
    }
21
    return r;
22
}

Das rufe ich nun zum Beispiel mit expectNumber(2) auf, um 2 Ziffern zu 
erwarten.
Nun wuerde ich erwarten, dass, wenn ich z.B. als erstes Zeichen 1 
uebermittle, r im ersten Schleifendurchlauf dann den Wert (10^1)*1=10 
annimmt. Tatsaechlich kommt aber 11 raus. Was ich mir nicht wirklich 
erklaeren kann.
Uebersehe ich was?

Viele Gruesse,
Martin

von gagast (Gast)


Lesenswert?

>10^(digits-i)
^ ist XOR, ist das gewollt?

von Martin S. (tungl)


Lesenswert?

gagast schrieb:
>>10^(digits-i)
> ^ ist XOR, ist das gewollt?
Oh. Ohhhh. Danke. Das soll natuerlich kein XOR sein, sondern ein "hoch". 
Und ich zerbrech mir Stunden den Kopf darueber, warum das jetzt nicht 
geht.

Vielen Dank fuer die Erleuchtung!

von Rolf M. (rmagnus)


Lesenswert?

Martin S. schrieb:
> int n = atoi(&input);

input ist ein char. atoi erwartet einen String, also ein 
nullterminiertes Array aus char.   Wenn du die Adresse von input 
übergibst, nimmt atoi das und dann noch alles, was danach zufällig so im 
Speicher steht, bis es dann eine 0 findet und wertet alles zusammen als 
den übergebenen String.

von Martin S. (tungl)


Lesenswert?

Rolf Magnus schrieb:
> input ist ein char. atoi erwartet einen String, also ein
> nullterminiertes Array aus char.   Wenn du die Adresse von input
> übergibst, nimmt atoi das und dann noch alles, was danach zufällig so im
> Speicher steht, bis es dann eine 0 findet und wertet alles zusammen als
> den übergebenen String.

Danke fuer die Erlaeuterung. Ich habe mir da auch schon Gedanken 
gemacht, aber so funktioniert es. Was waere denn die korrekte Loesung?

von Karl H. (kbuchegg)


Lesenswert?

Martin S. schrieb:

> Danke fuer die Erlaeuterung. Ich habe mir da auch schon Gedanken
> gemacht, aber so funktioniert es.

Das ist kein Argument. Es 'funktioniert' höchstens zufällig

> Was waere denn die korrekte Loesung?

  n = input - '0';

von Karl H. (kbuchegg)


Lesenswert?

und als ganzes wäre eine einfache Lösung

(und gewöhn dir an, dass wir bei 0 anfangen zu zählen)
1
    r = 0;
2
3
    for (i=0; i<digits; i++)
4
    {
5
        do {
6
          input = UARTReceive();
7
        } while (!characterIsNumber(input));
8
9
        r = 10*r + (input - '0'); 
10
    }

oder
1
     r = 0;
2
     i = 0;
3
4
     while( i < digits )
5
     {
6
       input = UARTReceive();
7
       if( characterIsNumber(input) )
8
       {
9
         r = 10*r + (input - '0');
10
         i++;
11
       }
12
     }


PS: dir ist bekannt, dass es eine Standardfunktion isdigit() gibt?

von Martin S. (tungl)


Lesenswert?

Vielen Dank noch fuer die Anregungen. Nein, war mir nicht bewusst, dass 
es die Funktion schon gibt. Habe eigentlich erst heute damit angefangen 
und bin noch nicht wirklich heimisch. ;-)

von Karl H. (kbuchegg)


Lesenswert?

Martin S. schrieb:
> Vielen Dank noch fuer die Anregungen. Nein, war mir nicht bewusst, dass
> es die Funktion schon gibt. Habe eigentlich erst heute damit angefangen
> und bin noch nicht wirklich heimisch. ;-)

Ein C-Buch durcharbeiten kann wahre Wunder bei fehlendem Wissen wirken.
zb
http://openbook.galileocomputing.de/c_von_a_bis_z/

von Peter D. (peda)


Lesenswert?

Martin S. schrieb:
> die ueber UART reinkommen, mit gibt und die
> so lang darauf wartet, bis genug Zeichen eingetroffen sind

Damit läuft man Gefahr, daß Dein Programm hängen bleibt und nichts 
anderes mehr machen kann.
Die übliche Methode ist daher, daß man von der UART in einen Puffer 
einliest. Und erst, wenn z.B. ein Endezeichen (z.B. CR,LF) emfangen 
wurde, übergibt man den Puffer zur Auswertung.
So wird nicht unnütz CPU-Zeit mit Warten vergeudet.


Peter

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.