Funktion, die Zahl aus Zeichen zusammenbastelt

OP #2707380
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
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.
OP
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?
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?
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

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 14 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.