Problem bei Variablenlänge bei sscanf



  • @Jackson00 sagte in Problem bei Variablenlänge bei sscanf:

    int ist bei meinem MC(16Bit MC)/Compilter 16Bit also gleich ob short oder int

    Das spielt keine Rolle.
    Anderer MC oder Compiler und schon hast du Probleme,

    Mach es gleich richtig.
    Ein Programm kann auch auf maximaler Warnstufe ohne Warnungen compilieren.



  • KA (*(char 😉 hatte ich irgendwo im Netz beim suchen gefunden ☺
    Normalerweise reichen für den MC und das was ich damit programmiere die rudimentären C-Befehle völlig, die Lib String ist die einzigste C-Lib die ich eingebunden habe. Und auch nur weil ich nicht wusste wie ich sonst Zahlen aus Strings extrahiere und ich auch noch ein paar andere Befehle wie strcpy , strcat, etc. für die Stingmanipulation benutze.

    Wie man sieht habe ich nicht wirklich gute C Kenntnisse... 😞

    @Wutz sagte in Problem bei Variablenlänge bei sscanf:
    Also dann so:

    unsigned tmp1, tmp2;

    if (2 == sscanf(Command, "%hu,%hu", &tmp1, &tmp2)) {
    Level[0] = (unsigned char)tmp1;
    Level[1] = (unsigned char)tmp2;
    }





  • die Zahl hinter dem % ist doch die max. Länge oder? Würde dann auch %3hu gehen? Dann könnte er theoretisch nur bis max. 999 lesen richtig?



  • Ja. Aber lass das h bleiben und nimm unsigned int für die Argumente. int (mit oder ohne unsigned) ist in der Regel so breit wie ein Maschinenwort.



  • da hat der Editor irgendwas gefressen, ich habe bei mir unsigned short tmp1, tmp2; im Code stehen...



  • @Jackson00 Wenn auf deinem µC ein int 16 bit breit ist, ist es ein short auch. Schreib einfach einfachen Code ^^.

    #define false 0
    #define true 1
    typedef int bool;
    
    bool is_in_range(int value, int lower_bound, int upper_bound)
    {
        return lower_bound <= value && value <= upper_bound);
    }
    
    bool foo(char const *command, char unsigned *levels)
    {
        int tmp1;
        int tmp2;
        if (sscanf(command, "%d,%d", &tmp1, &tmp2) != 2 ||
            !is_in_range(tmp1, 0x00, 0xff) || !is_in_range(tmp2, 0x00, 0xff))
        {
            // handle error, perhaps return an error code:
            return false;
        }
    
        // everything allright, go on:
        levels[0] = (char unsigned) tmp1;
        levels[1] = (char unsigned) tmp2;
        // ...
        return true;
    }
    
    // ...
    
    if (!foo(command, levels)) {
        // handle error
    }
    

    Eigentlich würde ich gerne mal das komplette Programm sehen.


    Premature Optimization is the root of all evil.



  • @Jackson00 sagte in Problem bei Variablenlänge bei sscanf:

    weil ich nicht wusste wie ich sonst Zahlen aus Strings extrahiere und ich auch noch ein paar andere Befehle wie strcpy , strcat, etc. für die Stingmanipulation benutze.

    void ExtractNumberFromString(char string[], int *number)
    {
         //calculate string length
         int length = 0;
         int i = 0;
    
         while(str[i])
         {
              length++;
         }
    
         //calculate number's highest power of ten
         int poweroften = 1;
    
         for(i = 0; i < length - 1; i++)
         {
              poweroften *= 10;
         }
    
         //extract number from string
         int number = 0;
    
         for(i = 0; i < length; i++)
         {
              number += (str[i] - '0') * poweroften;
    
              poweroften /= 10;
         }
    }
    


  • Warum nicht einfach atoi? Da ist die passende Behandlung von nicht-Ziffern schon mit drin.

    Und wieso Rückgabetyp void?
    Und wieso int* number als Out-Parameter?
    Und wieso selber zählen statt strlen?
    Und außerdem ist das Problem wohl mehrere Zahlen aus einem string zu lesen.



  • @DocShoe sagte in Problem bei Variablenlänge bei sscanf:

    Warum nicht einfach atoi? Da ist die passende Behandlung von nicht-Ziffern schon mit drin.

    Kann (und sollte) man nachher auch nehmen.

    Und wieso Rückgabetyp void?

    Ich war zu faul, nach unten zu scrollen, um am Ende der Funktion "return number;" zu schreiben. Sorry...

    Und wieso int* number als Out-Parameter?

    Ehrlich gesagt verwende ich Rückgabewerte gerne für Fehlercodes. Da kann man ja von halten, was man will.

    Und wieso selber zählen statt strlen?

    Ich programmiere solche Funktionen irgendwie gerne selbst. Das ist wie mit dem maßgeschneiderten Anzug: Es passt genau!

    Und außerdem ist das Problem wohl mehrere Zahlen aus einem string zu lesen.

    Also entweder die Dokumentation durchwühlen und dann die Standardfunktion nehmen, oder die Anzahl der Ziffern der jeweiligen Zahl ermitteln und dann die (angepasste) obige Funktion verwenden.



  • @Peter-Viehweger sagte in Problem bei Variablenlänge bei sscanf:

    maßgeschneiderten

    lol

    char const* str2ui(char const *str, unsigned *result)
    {
        *result = 0;
        for (; '0' <= *str && *str <= '9'; ++str) {  // nein, eigentlich isdigit()!
            *result *= 10;
            *result += *str - '0';
        }
        return str;
    }
    

    @Jackson00 Nein, nicht machen! Verwende die Standard Library immer wenn möglich!
    (Zum Üben rumspielen ist ein anderes Thema.)



  • @Peter-Viehweger sagte in Problem bei Variablenlänge bei sscanf:

    Das ist wie mit dem maßgeschneiderten Anzug: Es passt genau!

    Zumindest hast du Humor.



  • @Peter-Viehweger sagte in Problem bei Variablenlänge bei sscanf:

    Ich programmiere solche Funktionen irgendwie gerne selbst. Das ist wie mit dem maßgeschneiderten Anzug: Es passt genau!

    Du nähst deine Anzüge selbst? Respekt!



  • Nein, aber wenn ich nicht weiß, dass es bereits eine Standardfunktion gibt, was ja mal vorkommen kann, dann bin ich in der Lage, das Problem durch Implementieren einer eigenen Funktion zu lösen. Manchmal ist das der Unterschied zwischen "Funktioniert!" und"Funktioniert nicht!". 😜



  • @Peter-Viehweger sagte in Problem bei Variablenlänge bei sscanf:

    Manchmal ist das der Unterschied zwischen "Funktioniert!" und"Funktioniert nicht!".

    'tschuldige, aber was Du da oben gezeigt hast ist Müll.



  • 😢 😭 😭



  • @hustbaer Sag' mal weinst Du etwa oder ist es der Regen, der von deiner Nasenspitze tropft?



  • @Swordfish Das ist das Jesus-Baby das weint.



  • @Peter-Viehweger Da siehste mal was Du anrichtest!!


  • Mod

    @Peter-Viehweger : Da vielleicht nicht so richtig rüber kommt, was an dem Code schlecht ist, sondern nur dass er schlecht ist (Die Kritik von @DocShoe geht leider ziemlich an den Problemen vorbei und ist sogar teils falsch):

    • Errorcode als Rückgabewert ist ja ok, aber tu es halt auch!
    • Errorcode nicht nur vergessen, du hast halt überhaupt nix drin, dass deine Funktion bei unerwarteter Eingabe nicht irgendwelchen Unsinn macht
    • Du hast noch nie Funktionen für C-Strings geschrieben, oder? Das sieht man an deinem Programmiermuster: Länge messen indem man komplett zum Ende geht, dann bis zur Länge durchgehen und irgendwas machen. Kommt dir das nicht irgendwie unnötig gedoppelt vor? Stattdessen einfach bis zum Ende durchgehen und dabei machen, was man will. Länge unnötig.
    • Dafür, dass die Lösung "maßgeschneidert" sein soll, ist sie erstaunlich allgemein. Denn dein Problem war ja das Einlesen von zwei Zahlen, deine "Lösung" ist das Umwandeln eines C-Strings in eine Zahl. Wobei das aber eher ein Pluspunkt ist, denn wiederverwertbare, allgemeine Funktionen sind gut. Du hast aber halt etwas unnötigen Overhead.
    • Viele weitere Kleinigkeiten, z.B. fehlende const-Correctness
    • PS: Krasse Funktionsfehler, der Code funkioniert nicht einmal und du hast ihn offensichtlich nicht getestet. Siehe nächster Beitrag

    Besser:

    • Im Zweifelsfall immer die Standardbibliothek zum Vorbild nehmen (oder besser: Standardbibliothek nehmen!). Wobei das hier etwas doof ist, denn es gibt zwei Funktionen für die gleiche Aufgabe, atoi, und strtol & Co. Da muss man jetzt leider wissen (oder sich beim Lesen der Beschreibungen denken), dass strtol das neue, verbesserte atoi ist. Denn atoi hat einige Fehler in der Schnittstelle. Also mal strtol angucken und nachmachen (oder besser: Direkt benutzen!)
    • Zum Nachmachen brauchst du aber nicht weit gucken, denn @Swordfish hat es ziemlich perfekt vorgemacht. Daher: Die Lösung von Swordfish angucken und komplett verstehen. Jedes einzelne Zeichen. Er hat sich extra Mühe gegeben und nur die nötigsten der schwierigen Schreibweisen für C-Stringverarbeitung genutzt. Der "echte" Code von strtol ist garantiert eine Nummer schlimmer.

Anmelden zum Antworten