char pointer manipulation



  • ich habe die Ausgangslage etwas verallgemeinert.

    uint16_t krm
    

    ist hierbei fix - irgendeine 16 bit Zahl.

    @EOutOfResources
    meinst du so?
    uint8_t asd[2] = krm;



  • pampy schrieb:

    uint8_t asd[2] = krm;

    Nö, so:

    uint8_t asd[2] = {'1', '2'};
    


  • krm ist leider eine rückgabevariable einer funktion.

    uint8_t * ptr = "Hallo12"
            uint16_t krm; // Rückgabevar einer fkt
    
    	uint8_t * zeiger;
    	zeiger = ptr + 5;
    	*zeiger = (krm >> 8);
            ptr1 = ptr + 1;
    	*ptr1 = krm;
    

    mh.. Irgendwie komm ich auf keinen grünen Zweig.



  • In welchem Format willst du denn den Inhalt von krm darstellen? Willst du die Dezimaldarstellung des Wertes?



  • ja, in dezimal - wobei auch hex ok ist.



  • Dann ist wohl die sprintf()-Lösung von Dirk am geeignetsten für dich.



  • ich möchte es nicht einfach printen, sondern gleich im ptr manipulieren und abspeichern, geht dies nicht?



  • die printf-Familie ist umfangreicher als du denkst - neben dem einfachen printf() (für die Ausgabe nach stdout) gibt es noch fprintf() (Ausgabe in eine Datei), sprintf() (Ausgabe in ein char-Array - genau das hast du vor) sowie einige weitere Varianten.



  • Eine Lösung ohne die Hilfe von Funktionen aus der Standardbibliothek wäre, aus krm die Zehner- und Einerstelle mithilfe von Modulo- und Divisionsoperationen zu extrahieren und diese in die jeweiligen ASCII-Werte umzuwandeln. Dann kannst du die entsprechenden Zeichen im String verändern.

    Konkret könnte das Ganze so aussehen:

    char ptr[] = "Hallo12";
    unsigned short krm = 42; /* Kann jede beliebige Ganzzahl sein */
    
    ptr[5] = ((krm / 10) % 10) + '0'; /* Zehnerstelle */
    ptr[6] = (krm % 10)        + '0'; /* Einerstelle */
    

    Zu beachten ist, dass so alle höherwertigen Stellen ignoriert werden, wenn die Zahl größer als 99 ist. Die Klammern sind übrigens überflüssig, sollen es nur verdeutlichen.



  • Habe mittlerweile eine Lösung gefunden, trotzdem vielen Dank für die Tipps!!
    Super FOrum mit sehr netten Leute.

    Lösung:
    ich habs einfach mit *(ptr + i), statt ptr[] gelöst

    Nochmals danke!



  • Deine Lösung könnte interessant werden, wenn du mittels Pointer einfach den Inhalt überschreibst. Wie soll eine beliebiege 16bit Zahl auf 2 Stellen eingedampft werden oder keine benachbarten Speicherstellen überschreiben? Solche "Pointer Magic" ist "Bad Mojo".

    Gruß



  • durch hin und her shiften bzw casten entstehen doch keine Datenleaks, oder?



  • Du hast in "Hallo12" nur zwei Stellen Platz für Deine Ziffern - eine 16-Bit - Zahl kann aber 5 Stellen haben, wie also soll das passen?



  • Kann es vielleicht sein, dass du doch nur die beiden Bytes aus der 16-Bit-Zahl in den String schreibst, und nicht die Dezimaldarstellung der Zahl?



  • pampy schrieb:

    durch hin und her shiften bzw casten entstehen doch keine Datenleaks, oder?

    Doch genau da liegt der Hase im Pfeffer. Du überschreibst im Falle einer Zahl größer Dezimalwert 99 Speicherstellen die nicht zum String gehören und der Compiler kann das nicht erkennen, da du ihm mit Pointermagic seine Kontrolle entzogen hast. Der Befehl an sich, mittels char *(p+1) ein char zu schreiben ist für den Compiler i.O, die Zieladresse vielleicht nicht.

    Endet der String an einer ungeraden, nicht durch 4 teilbaren Adresse tritt erstmal kein Fehler auf, da bis zum nächhsten Wert bis zu 3 leere Füllbytes liegen.
    Endet der String an einer geraden, durch 4 teilbaren Adresse, dann folgt direkt darauf eine andere Variable. Probleme sind vorprogrammiert. Spätestens wenn der Compiler Optimierungen durchführen soll, um Füllbytes zu vermeiden.

    Du bist auf der sicheren Seite, wenn du *(p+1) nur dann anwendest, wenn du den zu manipulieren String in einen ausreichend großen Puffer umkopierst.
    Dann kannst du aber auch gleich die Standard-String-Funnktionen nutzen.

    Gruß


Anmelden zum Antworten