int in char * umwandeln



  • Nochmal vielen Dank für die vielen Antworten.

    Ich beschreibe mal genauer, was ich tun möchte:
    Ich besitze einen Roboter, der über Infrarot mit meinem PC kommunizieren soll.
    Mittels einer Funktion lnp_integrity_write(s,strlen(s)); kann der Roboter eine Nachricht zum PC schicken. Das Problem ist nun, dass ich immer nur Textnachrichten in Form von char * senden kann. Folgendes funktioniert:

    char *c = "hallo";
    lnp_integrity_write(s,strlen(s));
    

    Jetzt möchte ich aber nicht nur Text an den PC senden, sondern auch Integer, zum Beispiel die Helligkeit des Lichts. Und die muss ich dann in eine Form kriegen, die durch lnp_integrity_write() versendet werden kann.

    @Simon2 und TactX:
    Ja, die Einbindung von stdio.h ist auf meinem Roboter nicht vorgesehen. Daher funktioniert das sprintf() leider nicht.
    Ich glaube aber, dass ich eigene *.h-Dateien einbinden kann. Ich habe mir einfach mal eine stdio.h, die ich auf meinem PC gefunden habe, kopiert und benutzt.
    Diese braucht aber wiederum andere Dateien und ist ziemlich groß; ich habe auf meinem Roboter nur sehr wenig Speicher.
    Kann ich selbst eine stdio.h schreiben, die nur die Funktion sprintf beinhaltet und keine oder wenige andere Dateien braucht?



  • Nimm mal die Funktion aus meiner Lieblings-FAQ: http://c-faq.com/misc/hexio.html



  • nh2 schrieb:

    char *c = "hallo";
    lnp_integrity_write(s,strlen(s));
    

    hi,
    wenn du damit ein einzelnes zeichen versenden willst:

    char c = 'a';
    lnp_integrity_write (&c, 1);
    

    oder einen integer:

    int v = 0x1234;
    lnp_integrity_write ((char*)&v, sizeof(int));
    

    die bytes des integers werden dabei in der reihenfolge übertragen, in der sie im speicher stehen...
    :xmas2:



  • TactX schrieb:

    Simon2 schrieb:

    Sorry, wenn ich ein wenig harsch war.

    Harsch sein ist nicht das Problem. Das Problem ist wenn man selbst nicht recht hat 😉
    ...

    Echt ? Das war das Problem des OPs ?

    Erstaunliches tritt hier zutage.

    Gruß,

    Simon2.



  • ten schrieb:

    nh2 schrieb:

    char *c = "hallo";
    lnp_integrity_write(s,strlen(s));
    

    hi,
    wenn du damit ein einzelnes zeichen versenden willst:

    char c = 'a';
    lnp_integrity_write (&c, 1);
    

    oder einen integer:

    int v = 0x1234;
    lnp_integrity_write ((char*)&v, sizeof(int));
    

    die bytes des integers werden dabei in der reihenfolge übertragen, in der sie im speicher stehen...
    :xmas2:

    Ich verstehe nicht, warum, aber es werden total kryptische Zeichenfolgen gesendet!



  • Ganz einfach: ein int wird intern als Binärwert mit (typischerweise) 4 Byte Länge gespeichert - und wenn du den als char-Array interpretierst, wird jedes diesr Bytes als Einzelzeichen gelesen. Das heißt, du mußt die int-DAten auf Binärebene wieder zurückverwandeln:

    lnp_integrity_read(buffer);
    memcpy((char*)&v,buffer,sizeof(int));
    

    (wenn du etwas für Menschen lesbares übergeben willst, schau mal in die C++ FAQ zum Thema "Einmal String nach Zahl und zurück" (die meisten dort genannten Funktionen klappen auch unter C).



  • nh2 schrieb:

    ...
    Ich verstehe nicht, warum, aber es werden total kryptische Zeichenfolgen gesendet!

    ... weil ten einfach das getan hat, wonach Du zuerst gefragt hast. (int in char* konvertiert)
    Das ist aber nicht das, was Du willst/brauchst.
    Wie schon CStoll sagte: Einfach die (für Maschinen verständliche) interne Darstellung einer Zahl (int) auszugeben, hilft Dir nicht weiter (hast Du gerade festgestellt). Du musst die Zahl in einen für den Menschen lesbare Zahl umwandeln .. und das hat eigentlich nicht so sehr etwas damit zu tun, dass Du die Daten von einem Roboter an einen PC senden willst, als vielmehr, dass sich ein Mensch das ansehen soll.

    Dasselbe müsstes Du auch machen, wenn Du auf dem Roboter einen Display hättest oder eine Zahl auf dem PC hättest und die anzeigen möchtest.

    Um diese Umwandlung "Maschinendarstellung->Menschdarstellung" hinzubekommen, haben CStoll und ich Dir schon Tipps gegeben ... einfacher geht's leider nicht (wenn Du kein sprintf() oder itoa() hast.

    Gruß,

    Simon2.



  • Simon2 schrieb:

    Um diese Umwandlung "Maschinendarstellung->Menschdarstellung" hinzubekommen, haben CStoll und ich Dir schon Tipps gegeben ... einfacher geht's leider nicht (wenn Du kein sprintf() oder itoa() hast.

    Doch - der Roboter sendet den int-Wert als Byte-Haufen und der PC auf der Empfänger-Seite erkennt den Datentyp und wandelt den Wert in etwas lesbares um (auf der PC-Seite dürften sprintf() und Konsorten kein Problem sein).



  • CStoll schrieb:

    Simon2 schrieb:

    Um diese Umwandlung "Maschinendarstellung->Menschdarstellung" hinzubekommen, haben CStoll und ich Dir schon Tipps gegeben ... einfacher geht's leider nicht (wenn Du kein sprintf() oder itoa() hast.

    Doch - der Roboter sendet den int-Wert als Byte-Haufen und der PC auf der Empfänger-Seite erkennt den Datentyp und wandelt den Wert in etwas lesbares um (auf der PC-Seite dürften sprintf() und Konsorten kein Problem sein).

    Äh ....
    an "einfacher geht's nicht, wenn man kein sprintf() oder itoa() hat" ist doch nichts falsch, oder ?

    Es sieht ganz danach aus, als hätte der OP die Option "Veränderung der PC-Schnittstelle" nicht (und selbst wenn, habe ich durchaus darauf hingewiesen, dass man eine entsprechende Umwandlung auch auf dem PC machen muss - und sei es mit sprintf()).

    Bislang hat der OP immer versucht, mit einem "geschickten cast" um diese Arbeit herumzukommen und das kann er IMO nicht.

    Gruß,

    Simon2.

    P.S.: Damit, einen int einfach so über Maschinengrenzen (mit unterschiedlicher Architektur) hinwegzusenden, wäre ich ebenfalls sehr vorsichtig ...



  • CStoll schrieb:

    Ganz einfach: ein int wird intern als Binärwert mit (typischerweise) 4 Byte Länge gespeichert - und wenn du den als char-Array interpretierst, wird jedes diesr Bytes als Einzelzeichen gelesen. Das heißt, du mußt die int-DAten auf Binärebene wieder zurückverwandeln:

    lnp_integrity_read(buffer);
    memcpy((char*)&v,buffer,sizeof(int));
    

    Ich glaube, dass das mit memcopy funktionieren kann. Ich habe als Test erst einmal eine normale Zeichenkette benutzt. Diese gebe ich auf dem Display des Robos aus (mit cputs(<<TEXT>>);). Das müsste genau so funktionieren wie lnp_integry_write(), ist aber einfacher zu überprüfen.

    char v[3] = "ha2";
    char buffer[3];
    
    memcpy(buffer,v,3);	
    
    cputs(buffer);
    

    Das funktioniert. Auf dem Display steht ha2.
    Jetzt versuche ich es mit einem Integer.
    Ich dachte da an sowas:

    int i = 33;
    char buffer[30];
    
    memcpy(buffer,&i,sizeof(int));
    
    cputs(buffer);
    

    Geht aber nicht. Was mache ich falsch?



  • Du liest nur die Hälfte des Threads - in einem int steht eine binäre Repräsentation des Zahlenwertes (und der sieht, als char* interpretiert, katastrophal aus). Für die Darstellung kommst du nicht darum, itoa() und Konsorten zu verwenden (wenn nicht vorhanden, mußt du es nachprogrammieren).

    (PS: der String "ha2" benötigt übrigens 4 Byte (eins für das Stringende-Zeichen '\0'), da ist dein Test-Array etwas zu kurz gewählt)



  • Simon2 schrieb:

    P.S.: Damit, einen int einfach so über Maschinengrenzen (mit unterschiedlicher Architektur) hinwegzusenden, wäre ich ebenfalls sehr vorsichtig ...

    für sowas muss man eigentlich ein protokoll benutzen, in dem genau festgelegt ist, wie ein 'int' für die übertragung auszusehen hat. erst recht, wenn man auch zwischendurch mal andere datentypen, wie strings oder doubles verschicken will...
    :xmas2:

    edit: was ganz einfaches ist z.b. das hier: http://en.wikipedia.org/wiki/Type-length-value



  • ten schrieb:

    ...
    für sowas muss man eigentlich ein protokoll benutzen...

    Genau das wollte ich damit ausdrücken !

    Allerdings kann man als Protokoll oftmals durchaus die ASCII-String-Darstellung nehmen.

    Gruß,

    Simon2.



  • Simon2 schrieb:

    Allerdings kann man als Protokoll oftmals durchaus die ASCII-String-Darstellung nehmen.

    kann man. es gibt ja genügend erfolgreiche beispiele wie z.b. HTTP. nachteilig dabei ist nur, dass textbasierte protokolle empfangsseitig schwieriger auseinanderzufrickeln sind als irgendwelche binärformate....

    btw: man könnte ja auch XML nehmen, aber das machen nur total durchgeknallte 😉

    :xmas2:



  • CStoll schrieb:

    Für die Darstellung kommst du nicht darum, itoa() und Konsorten zu verwenden (wenn nicht vorhanden, mußt du es nachprogrammieren).

    Würde ich gerne machen.
    Wie kann ich das denn nachprogrammieren?



  • Da sieht man mal wie aufmerksam du hier mitliest. Einen Link zu einer Implementierung so einer Funktion hab ich schon vor einer ganzen Weile hier gepostet 👎



  • Hab ich schon gelesen, aber noch nicht ganz verstanden.
    num soll der zu konvertierende Integer sein und base? Soll das das System sein? Also für das Dezimalsystem zum Beispiel

    char * baseconv(33, 10)

    Stimmt das so?

    Und das was da herauskommt ist dann so wie ein char * c = "33"?



  • Probiers doch einfach mal aus 🙄



  • Danke, es funktioniert!
    Ich war mir unsicher, deshalb habe ich lieber noch einmal nachgefragt 😃


Anmelden zum Antworten