Gast
#4702894
Hallo, in einer Mikrocontroller Applikation soll ein Integer-Wert in ein String umgewandelt werden.
1 | |
2 | |
In cip soll dan der string "192.168.1.12" drin stehen Wie könnte sowas in Ansi C realisiert werden?
|
Anzeige
|
Ansi C: Convertierung int to string
Gast
#4702894
Hallo, in einer Mikrocontroller Applikation soll ein Integer-Wert in ein String umgewandelt werden.
In cip soll dan der string "192.168.1.12" drin stehen Wie könnte sowas in Ansi C realisiert werden? Mit sprintf und etwas Schieberei
Gast
#4702899
Entwickler schrieb: > Mikrocontroller Entwickler schrieb: > unsigned int Das wird so nicht funktionieren da dein int warscheinlich (du hast den Controller nicht genannt) nur 16 Bit breit sein wird ..... Entwickler schrieb: > char* cip Das wird nicht funktionieren da du nur einen Pointer auf einen String reserviert hast. Der reservierte Speicherbereich dazu fehlt aber ..... Wenn dir die Schieberei nicht gefällt, mach eine union mit einem char-Array und dem unsigned int. Zur Umwandlung der Zahl kannst du auch itoa nehmen. itoa ist allerdings nicht in Ansi-C enthalten, aber auf den meisten Compilern für Mikrocontroller vorhanden. Die passenden Suchwörter für Google wären snprintf, printf und itoa, um eine beliebige Ganzzahl in einen Char umzuwandeln. Natürlich musst du deine 32bit in vier mal acht Bit zerhacken, jeweils in einen Char umwandeln und zwischendurch noch jeweils einen Punkt einfügen. Moin, C-Libraries, die auf geheimen Microcontrollern laufen, koennten evtl. auch die Funktion inet_ntoa() kennen, die sowas aehnliches hinkriegt. Gruss WK Ich meinte oben natürlich char-Array statt char
Gast
#4702925
Dergute W. schrieb: > auf geheimen Microcontrollern Zumindest scheint der geheime µC ein 32 Bit Typ zu sein, sonst wäre der "unsigned int" wahrscheinlich zu klein für den Wert. Insofern wächst die Wahrscheinlichkeit dass libs zu IP existieren und Funktionen wie inet_addr(), inet_aton() und inet_ntoa() schon existieren. Vieleicht mal da schauen: http://www.gnu.org/software/libc/manual/html_node/Host-Address-Functions.html
Gast
#4702928
Dirk B. schrieb: > Wenn dir die Schieberei nicht gefällt, mach eine union mit einem > char-Array und dem unsigned int. ? Das hätte ich gerne mal ausprogrammiert gesehen.
Gast
#4702933
Der Andere schrieb: > sonst wäre der > "unsigned int" wahrscheinlich zu klein für den Wert. Die warscheinlichere Version ist dass der TO nicht weiss was er da wirklich tut. Denn er hält es ja auch nicht für nötig auf den Typ des Controllers hinzuweisen. Entwickler schrieb: > In cip soll dan der string "192.168.1.12" drin stehen > > Wie könnte sowas in Ansi C realisiert werden? Zum Beispiel so:
Gast
#4702941
Oder etwas übersichtlicher: unsigned int iip = 0xc0a8010c; unsigned int ip1; unsigned int ip2; unsigned int ip3; unsigned int ip4; char cip [16]; ip4 = iip & 0xff; iip = iip >> 4; ip3 = iip & 0xff; iip = iip >> 4; ip2 = iip & 0xff; iip = iip >> 4; ip1 = iip & 0xff; sprintf ( cip, "%d.%d.%d.%d", ip1, ip2, ip3, ip4 );
Gast
#4702958
So?
Beim Linken "-lwsock32" nicht vergessen...
Gast
#4702968
Oder eben doch geschoben:
Gast
#4702974
Entwickler schrieb: > In cip soll dan der string "192.168.1.12" drin stehen Heute noch IPv6 inkompatibel programmieren ? Amateur schrieb: > Oder etwas übersichtlicher: Kaum. Tim T. schrieb: > So? Eher nicht, die byte-order der int auf char[4] ist maschinenabhängig.
Gast
#4702982
MaWin schrieb: > Tim T. schrieb: >> So? > > Eher nicht, die byte-order der int auf char[4] ist maschinenabhängig. Dafür ist htonl doch drin... Und bevor auch noch am int gemosert wird: #include <stdint.h> und uint32_t ip = 0xc0a8010c; nehmen
Gast
#4702988
Tim T. schrieb: > Und bevor auch noch am int gemosert wird: So lernt der TO nix dazu .....
Gast
#4702998
Frickelfritze schrieb: > Tim T. schrieb: >> Und bevor auch noch am int gemosert wird: > > So lernt der TO nix dazu ..... Als ob dieses Forum dazu da ist den Leuten zu helfen, pffft. Hier geht es nur darum an allem rumzumosern, klug zu scheissen, Bildformate und Rechtschreibung zu kritisieren, den TO runterzuputzen und möglichst weit von einer einfachen Lösung fern zu halten.
Gast
#4702999
Frickelfritze schrieb: > So lernt der TO nix dazu ..... Manche Aussagen sind so dermaßen abwegig, dass noch nicht einmal das Gegenteil richtig ist.
Gast
#4703015
Tim T. schrieb: > So? Die Verwendung einer union zur Daten-Konvertierung ist undefined behaviour in Ansi C, und je nach Plattform ist die IP-Adresse verdreht! (Littie/Big Endian). Daher ist die Lösung mit Bitshifts besser, weil sie immer funktioniert, wie hier: Mark B. schrieb: > Zum Beispiel so: Tim T. schrieb: > Oder eben doch geschoben: Das ist falsch so, denn deine Bitshifts funktionieren ohne htonl korrekt, mit htonl gehts aber auf manchen Plattformen schief! Richtig gewollt aber falsch gemacht :-)
Gast
#4703025
Dr. Sommer schrieb: > Tim T. schrieb: >> So? > Die Verwendung einer union zur Daten-Konvertierung ist undefined > behaviour in Ansi C, und je nach Plattform ist die IP-Adresse verdreht! > (Littie/Big Endian). Nein, das union ist sehrwohl definiert, die daten im int jedoch nicht, das wurde durch htonl korrigiert. > > Daher ist die Lösung mit Bitshifts besser, weil sie immer funktioniert, > wie hier: Öhm, nein. > Mark B. schrieb: >> Zum Beispiel so: > > Tim T. schrieb: >> Oder eben doch geschoben: > Das ist falsch so, denn deine Bitshifts funktionieren ohne htonl > korrekt, mit htonl gehts aber auf manchen Plattformen schief! Richtig > gewollt aber falsch gemacht :-) Und wieder nein.
Gast
#4703029
Tim T. schrieb: > Öhm, nein. kannst du das begründen? > Und wieder nein. das auch?
Gast
#4703050
Tim T. schrieb: > Nein, das union ist sehrwohl definiert, die daten im int jedoch nicht, > das wurde durch htonl korrigiert. Ah stimmt, das htonl hab ich übersehen. Seltsamer Ansatz aber sollte funktionieren. Tim T. schrieb: > Öhm, nein. Öhm, doch. z.B. "(0x12345678 >> 8) & 0xFF" liefert immer 0x56, unabhängig von der Byte-Reihenfolge der Plattform. Daher ist ein solcher Ansatz dem Umweg über eine union+htonl immer vorzuziehen... Tim T. schrieb: > Und wieder nein. Doch. Tim T. schrieb: > ip = htonl(ip); Verdreht auf Little-Endian Architekturen die Reihenfolge. > sprintf(cip, "%d.%d.%d.%d\n", ip & 0xff, (ip >> 8) & 0xff, (ip >> 16) > & 0xff, (ip >> 24) & 0xff); Gibt bei gegebenem Inhalt von "ip" immer das gleiche aus unabhängig von der Plattform. Da du also am Anfang je nach Plattform 1x verdrehst, kommt auf BE/LE Systemen jeweils was anderes heraus. Hier noch ein Ansatz mit getnameinfo. Dieser funktioniert auf POSIX-kompatiblen Systemen. Der Vorteil ist hier, dass der auch trivial auf IPv6 umgebaut werden kann (mit sockaddr_in6 statt sockaddr_in). getnameinfo kann direkt mit der Adresse aus z.B. accept() oder getaddrinfo() genutzt werden, sodass das Programm komplett unabhängig von IPv4 vs. IPv6 wird.
Gast
#4703076
Dr. Sommer schrieb: > Tim T. schrieb: >> So? > Die Verwendung einer union zur Daten-Konvertierung ist undefined Er ist in guter Gesellschaft: https://msdn.microsoft.com/en-us/library/windows/desktop/ms738571(v=vs.85).aspx
Nenn mal ein ABI bei dem das nicht so funktionieren kann (korrekte Verwendung von htonl und ntohl natürlich vorausgesetzt).
Gast
#4703096
Bernd schrieb: > Er ist in guter Gesellschaft: Du verwendest Microsoft als Referenz bei Fragen zum C-Standard? Wo sich Microsoft doch so gut mit Standards zu Programmiersprachen und Betriebssystemen auskennt... ;-) Wie z.B. das "FAR" genau da, das sieht total nach C-Standard aus. In einer C Standard Library ist eine union aber schon besser aufgehoben, da diese onehin plattformspezifisch ist. Bernd schrieb: > Nenn mal ein ABI bei dem das nicht so funktionieren kann (korrekte > Verwendung von htonl und ntohl natürlich vorausgesetzt). Darum gehts nicht... Ich habe sogar geschrieben dass es funktionieren müsste. Dennoch ist es so, dass der C-Standard da einfach sagt "undefined". Im C-Standard steht auch nichts von ntohl. Eine Undefiniertheit in der Programmiersprache mit einer Betriebssystem-Funktion auszubügeln ist unschön. Bitshifts sind die bevorzugte, einfache, sichere, wohldefinierte Methode. Ich verstehe nicht, warum sich da alle gegen wehren? Mark Brandis hat eine einfache, korrekte, standard-konforme, immer funktionierende Lösung gepostet. Diese ist den anderen Frickelein, die "funktionieren müssten", zu bevorzugen...
Gast
#4703392
Dr. Sommer schrieb: > Wie z.B. das "FAR" genau da, das sieht total nach C-Standard aus. Was hat denn der C-Standard gegen Preprozessor Makros?
Gast
#4703407
guest schrieb: > Was hat denn der C-Standard gegen Preprozessor Makros? Windowsspezifische Makros für far/near pointer Unterscheidung sind nicht gerade portabel. Ist zum Glück nur ein Relikt ohne Bedeutung.
Gast
#4703454
Dr. Sommer schrieb: > guest schrieb: >> Was hat denn der C-Standard gegen Preprozessor Makros? > Windowsspezifische Makros für far/near pointer Unterscheidung sind nicht > gerade portabel. Ist zum Glück nur ein Relikt ohne Bedeutung. far/near Pointer sind sowieso Platform-/Compilerspezifisch. Von daher wird das durch die Makros noch eher portabel als ohne. Außerdem ist der Rest drum rum auch nicht portabel, nennt sich ja nicht Umsonst Platform SDK bzw. Windows SDK. Das mit dem Relikt ist natürlich richtig. Dr. Sommer schrieb: > Dennoch ist es so, dass der C-Standard da einfach sagt > "undefined". ich meine, in diesem Fall sagt er nicht "undefined", sondern "implementation defined". D.h. was dabei passiert, steht nicht im C-Standard, sondern im Compilerhandbuch. Antwort schreibenBitte melde dich an, um einen Beitrag zu schreiben. |
Anzeige
|