mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Konvertierung unsigned int --> unsigned char*


Autor: user (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo, auf einem Mikrocontrollersystem sollen unsigned int Werte in ein 
unsigned char Array umgewandelt werden. Beim Debuggen ist festzustellen, 
dass die Adressen von test1 und test2 gleich sind. Folglich sind die 
Inhalte ebenso gleich. Woran könnte dies liegen?
unsigned char* test1;
unsigned char* test2;

test1 = Convert(0x12345678);
test2 = Convert(0x23456789);

Funktion
unsigned char* Convert(unsigned int value)
{
    unsigned char x[4] = {0};
    unsigned char result[12] = {0};

    x[0] = (unsigned char)value & 0xFF;
    x[1] = (unsigned char)(value >> 8) & 0xFF;
    x[2] = (unsigned char)(value >> 16) & 0xFF;
    x[3] = (unsigned char)(value >> 24) & 0xFF;

    sprintf(result,"%d.%d.%d.%d", x[3], x[2], x[1], x[0]);

    return result;
}

Autor: fop (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Convert Funktion ist böse. Sie enthält einen dicken Fehler !
Ihr Array result ist lokal und nachdem die Funktion endet mausetot !
Die Funktion gibt aber einen Pointer auf die Leiche zurück. Extra Pfui 
!!!

Autor: user (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Besser wäre die Funktion so umzusetzen.
void Convert(unsigned int value, unsigned char *dest)
{
        dest[0] = (value& 0xff000000) >> 24;
        dest[1] = (value& 0x00ff0000) >> 16;
        dest[2] = (value& 0x0000ff00) >>  8;
        dest[3] = (value& 0x000000ff)      ;
}

Autor: Lothar M. (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
1 lesenswert
nicht lesenswert
user schrieb:
> sollen unsigned int Werte in ein unsigned char Array umgewandelt werden
Ich interpretiere das so, dass du da aus einem Integer einen 
ASCII-String machen willst.

user schrieb:
> Beim Debuggen ist festzustellen, dass die Adressen von test1 und test2
> gleich sind.
Zeig doch mal, was du da meinst..

> Folglich sind die Inhalte ebenso gleich.
Welche Inhalte?

> Woran könnte dies liegen?
Die Adressen von test1 und test2 können nicht gleiche sein. Nur die 
Adressen, die dort an den Adressen gespeichert sind, können gleich sein. 
Und genau das passiert, denn deine Convert() Funktion gibt beide Male 
den selben Zeiger zurück.
Noch schlimmer: das ist ein Zeiger auf eine Variable result, die nur 
temporär in der Convert() Funktion existiert!

Autor: Frank M. (ukw) (Moderator) Benutzerseite
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Eigentlich ist es sogar ein Doppelfehler:

1. Die Funktion gibt einen Zeiger auf eine lokale Variable zurück,
   welche nach Beenden der Funktion stirbt.

2. Macht man die Variable result static, damit sie den Aufruf überlebt,
   nützt dies auch nichts. In diesem Fall würde auch 2x derselbe Pointer
   zurückgegeben werden.

Eine Lösung:

In der aufrufenden Funktion (z.B. main() jeweils den Buffer result1 und 
result2 runtergeben, damit Convert() diese füllen kann.

Die beste Lösung:

Der TO sollte sich ein C-Buch schnappen und die Programmiersprache 
systematisch lernen. So wird das nix.

Autor: Joe F. (easylife)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Besser so:

unsigned char result1[12];
unsigned char result2[12];

Convert(result1, 0x12345678);
Convert(result2, 0x23456789);

void Convert(unsigned char* result, unsigned int value)
{
    unsigned char x[4] = {0};

    x[0] = (unsigned char)value & 0xFF;
    x[1] = (unsigned char)(value >> 8) & 0xFF;
    x[2] = (unsigned char)(value >> 16) & 0xFF;
    x[3] = (unsigned char)(value >> 24) & 0xFF;

    sprintf(result,"%d.%d.%d.%d", x[3], x[2], x[1], x[0]);
}


: Bearbeitet durch User
Autor: Peter D. (peda)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Man sollte auch beachten, daß auf vielen MCs "unsigned int" nur 
16-bittig ist.
Besser wäre daher, uint32_t zu verwenden (stdint.h).

Autor: Frank M. (ukw) (Moderator) Benutzerseite
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Joe F. schrieb:
> unsigned char result1[12];
> unsigned char result2[12];
> [...]
>     sprintf(result,"%d.%d.%d.%d", x[3], x[2], x[1], x[0]);
> }

Autsch! Buffer-Overflow!

Nur 12 Zeichen Platz für die IP-Adresse (denn um solch eine geht es ja 
wohl) "123.123.123.123"!

Korrekt wäre:

unsigned char result1[16];
unsigned char result2[16];

Denn wir brauchen

   4 x 3 Zeichen für die Dezimalzahlen
   3 x 1 Zeichen für die Punkte
   1 x 1 Zeichen für die Terminierung
   ===================================
   16    Zeichen insgesamt.

Autor: user (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich muss eine ip string "192.168.0.34" in ein char Array umwandeln.

Autor: Paul (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
warum ist es hier eigentlich
void Convert

was würde den int Convert ausgeben?
Nur 0 oder 1 für Funktion Fehlerfrei verarbeitet?

Autor: Frank M. (ukw) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Frank M. schrieb:
> Autsch! Buffer-Overflow!
>
> Nur 12 Zeichen Platz für die IP-Adresse (denn um solch eine geht es ja
> wohl) "123.123.123.123"!

Ich sehe gerade: Der TO hat denselben Fehler gemacht im 
Urprungs-Programm.

user schrieb:
> Ich muss eine ip string "192.168.0.34" in ein char Array umwandeln.

Das meinst Du jetzt nicht ernst, oder? Ein ip string ist ein char Array.
Du meinst tatsächlich: "Ich muss eine 32-Bit-IP-Adresse in einen IP 
String bzw. char-Array umwandeln".

Paul schrieb:
> was würde den int Convert ausgeben?
> Nur 0 oder 1 für Funktion Fehlerfrei verarbeitet?

Ja, korrekt. Aber im Moment findet ja keine Prüfung in der Funktion 
statt. Man könnte natürlich prüfen, ob der Buffer, der heruntergegeben 
wird, überhaupt die insgesamt 16 Zeichen fassen kann. Dann wäre 0 oder 1 
auf jeden Fall sinnvoll - oder Unix-like: 0 = OK, -1 = Error. Aber das 
ist Geschmackssache.

: Bearbeitet durch Moderator
Autor: Frank M. (ukw) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
user schrieb:
> Ich muss eine ip string "192.168.0.34" in ein char Array
> umwandeln.

Und weil diese konkrete IP-Adresse nur 12 Stellen hat, machst Du Dein 
char-Array auch nur 12 Stellen lang? Du hast einfach obige Adresse 
abgezählt?!? Es gibt durchaus IP-Adressen, die mehr Ziffern haben, z.B. 
"192.168.178.100".

Du musst immer die maximal mögliche Länge beachten! Immer! Das wäre (wie 
ich oben bereits schrieb) 16, denn Du hast auch noch vergessen, dass das 
Terminierungszeichen '\0' auch noch ein weiteres Byte (=Zeichen) in dem 
Array beansprucht.

Autor: user (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok vielen Dank für eure untersützung.

So funktioniert es:
void  Convert(unsigned int value, unsigned char* result)
{
    unsigned char bytes[4] = {0};

    bytes[0] = (unsigned char)value & 0xFF;
    bytes[1] = (unsigned char)(value >> 8) & 0xFF;
    bytes[2] = (unsigned char)(value >> 16) & 0xFF;
    bytes[3] = (unsigned char)(value >> 24) & 0xFF;

    sprintf(&result[0],"%d.%d.%d.%d", bytes[3], bytes[2], bytes[1], bytes[0]);
}

Verwendung der Funktion Convert:
unsigned char src_addr[16];
unsigned char dst_addr[16];

Convert(0xc0a8000d, src_addr);
Convert(0xc0a8000e, dst_addr);

Autor: Frank M. (ukw) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
user schrieb:
> sprintf(&result[0], ...

Das kannst Du auch so schreiben:
  sprintf(result, ...

Ist einfacher und lesbarer. Und man muss nicht soviel tippen. Beide 
Ausdrücke

  &result[0]
und
  result

sind äquivalent.

Allgemein gilt:

  &result[n]
ist äquivalent zu
  result + n

Steht in Deinem C-Buch unter Pointer-Arithmetik.

: Bearbeitet durch Moderator
Autor: Mikro 7. (mikro77)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
user schrieb:
> Ok vielen Dank für eure untersützung...

--Gibt es einen besonderen Grund, dass das Ergebnis ein (unsigned char*) 
statt eines (üblichen) char* ist?
--Oben wurde auf uint32_t hingewiesen. Damit ist man auf der sicheren 
Seite.
--Anstatt einen Kommentar zu schreiben, dass der Aufrufer einen 16-Byte 
Puffer zur Verfügung stellen muss, kann man das auch im Funktionskopf 
definieren.
#include <stdio.h>
#include <stdint.h>

void convert(uint32_t i,char(*buffer)[16])
{
  unsigned b0 = (unsigned char)i ;
  unsigned b1 = (unsigned char)(i >>  8) ;
  unsigned b2 = (unsigned char)(i >> 16) ;
  unsigned b3 = (unsigned char)(i >> 24) ;
  sprintf(*buffer,"%u.%u.%u.%u",b3,b2,b1,b0);
}

int main()
{
  uint32_t i1=0x12345678 ; char s1[16] ; convert(i1,&s1) ;
  uint32_t i2=0x23456789 ; char s2[16] ; convert(i2,&s2) ;
  printf("(1) %x -> %s\n",i1,s1) ;
  printf("(2) %x -> %s\n",i2,s2) ;
  return 0 ;
}

Autor: Frank M. (ukw) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mikro 7. schrieb:
> --Anstatt einen Kommentar zu schreiben, dass der Aufrufer einen 16-Byte
> Puffer zur Verfügung stellen muss, kann man das auch im Funktionskopf
> definieren.

Dafür holst Du aber direkt mit der Keule aus und übergibst statt dem 
Array einen Pointer auf ein Array - das ergibt eine Dimension mehr.

Ob das der TO mit seinem Wissenstand noch versteht? Das ist schon 
"höhere Kunst" ;-)

Außerdem schützt es nicht vor Buffer-Overdflow. Ersetze alle drei 
Vorkommnisse von [16] durch [12]. Das Programm wird nachwievor 
anstandslos übersetzt, auch mit -Wall.

: Bearbeitet durch Moderator
Autor: Mikro 7. (mikro77)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Frank M. schrieb:

> das ergibt eine Dimension mehr.

Wo ist das Problem?

> Außerdem schützt es nicht vor Buffer-Overdflow.

Doch. Sogar zur Compilezeit!

> Ersetze alle drei
> Vorkommnisse von [16] durch [12]. Das Programm wird nachwievor
> anstandslos übersetzt, auch mit -Wall.

"Alle drei"... also auch in der Funktionsdefinition... das ist jetzt 
nicht dein ernst, oder?

: Bearbeitet durch User
Autor: Frank M. (ukw) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mikro 7. schrieb:

> Wo ist das Problem?

Ich habe da kein Problem, ich arbeite teilweise mit drei oder gar vier 
Sternchen in Funktionsparametern ;-)

Ich sehe das Problem eher beim TO, dessen Wissensstand man ganz gut 
abschätzen kann.

> "Alle drei"... also auch in der Funktionsdefinition... das ist jetzt
> nicht dein ernst, oder?

Doch, ist mein Ernst.

Schau Dir das Ausgangsposting an. Dort schrieb der TO innerhalb von 
Convert():

unsigned char result[12] = {0};

Wenn ihn hier keiner darauf hingewiesen hätte, dass da 16 und nicht 12 
stehen muss, warum hätte er dann im Funktionsparameter von convert() 
dann [16] statt 12 geschrieben? Göttliche Eingebung? Nein, er hätte bei 
Verwendung Deiner Methode auch im Funktionsparameter 12 geschrieben und 
einen Buffer-Overflow provoziert.

Außerdem hat Dein Vorschlag neben der erhöhten Komplexität noch einen 
Nachteil: Ich kann lediglich Buffer übergeben, die exakt 16 Bytes groß 
sind. Einen größeren kann ich dann nicht übergeben, nämlich wenn ich 
nach dem Aufruf noch etwas anhängen will, wie z.B. " ist meine 
IP-Adresse".

Das folgende schützt tatsächlich vor einem Buffer-Overflow - auch wenn 
der Programmierer die 12 statt 16 verwendet:
#include <stdio.h>
#include <stdint.h>

void convert (uint32_t i, char * buffer, size_t size)
{
    unsigned b0 = (unsigned char)i;
    unsigned b1 = (unsigned char)(i >>  8);
    unsigned b2 = (unsigned char)(i >> 16);
    unsigned b3 = (unsigned char)(i >> 24);
    snprintf (buffer, size, "%u.%u.%u.%u", b3, b2, b1, b0);
}

int main()
{
  uint32_t i1=0x12345678; char s1[16]; convert (i1, s1, sizeof(s1));
  uint32_t i2=0x23456789; char s2[16]; convert (i2, s2, sizeof(s2));

  printf ("(1) %x -> %s\n", i1, s1);
  printf ("(2) %x -> %s\n", i2, s2);
  return 0;
}

Hier kannst Du alle Stellen von [16] durch [12] ersetzen. Das Programm 
wird nicht abstürzen oder das RAM irgendwo zerbröseln. Ok, 
unvollständige Werte wird es ausgeben, aber das ist halt ein 
Programmfehler. Aber es passiert kein Buffer-Overflow, der z.B. von 
Hackern ausgenutzt werden kann, um Code ins Programm zu injizieren - wie 
es schon oft in der Vergangenheit vorgekommen ist.

Außerdem kannst Du auch größere Buffer übergeben - noch ein Vorteil.

: Bearbeitet durch Moderator
Autor: Mikro 7. (mikro77)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Frank M. schrieb:
> Ich sehe das Problem eher beim TO, dessen Wissensstand man ganz gut
> abschätzen kann.

In C: Wenn man etwas modifizieren will, übergibt man einen Pointer 
darauf. Ist für einen Einsteiger straight forward. So auch in meinem 
Beispiel.

Schwerer zu verstehen ist hingegen, dass ein Array implizit einen 
Pointer auf das erste Element darstellt, Arrays in C eigentlich gar 
keine Arrays sind (keine Längeninfo zur Laufzeit) und Arrays nicht 
by-value übergeben werden können... Aber da muß man dann iwann durch. 
;-)

> Wenn ihn hier keiner darauf hingewiesen hätte, dass da 16 und nicht 12
> stehen muss, warum hätte er dann im Funktionsparameter von convert()
> dann [16] statt 12 geschrieben? Göttliche Eingebung?

Die Übergabe von Pointern auf statische (fixe) Arrays ermöglicht das 
Festellen von "ungültigen" (anderen) Puffergrößen zur Compilezeit. Nicht 
mehr und nicht weniger.

Dieses Feature mit deiner Begründung abzulehen... kopfschüttel

> Außerdem hat Dein Vorschlag...

Da stimme ich dir zu. Man kann Größen auch dynamisch zur Laufzeit 
verwalten (häufig muss man das sogar). Der Programmierer muss 
entscheiden, was in seiner Anwendung sinnvoll ist.

Edit: Spelling

: Bearbeitet durch User
Autor: Frank M. (ukw) (Moderator) Benutzerseite
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Mikro 7. schrieb:
> In C: Wenn man etwas modifizieren will, übergibt man einen Pointer
> darauf.

Genau: Man will in diesem Beispiel chars modifizieren, also übergibt man 
einen Pointer drauf, das wäre also (char *). Du übergibst aber einen 
Pointer auf ein ganzes Array, also eine Dimension mehr, als nötig ist. 
Übergibst Du auch (int **), wenn Du lediglich ints modifizieren willst?

> Dieses Feature mit deiner Begründung abzulehen... kopfschüttel

Okay, vielleicht überzeugt Dich folgender Blickwinkel:

Es gab und gibt Buffer-Overflows in C. Die gibt es und die wird es auch 
zukünftig geben. Der Grund ist meistens darin zu finden, dass der 
Programmierer

    1. die erforderliche Länge eines Buffers falsch berechnet hat

oder

    2. dass die Funktion, die den Buffer füllt, nicht auf die Länge
       des Buffers achtet.

Dein Beispiel schützt (bedingt) vor 2, aber nicht vor 1.
Mein Beispiel, das wesentlich simpler gestrickt ist und deshalb auch von 
einem fortgeschrittenen Anfänger verstanden wird, deckt beide Punkte ab.

Wenn Du auch diese Argumentation ablehnst, dann sag mir bitte, was an 
meiner einfacheren Lösung schlechter ist als an Deiner komplexeren. Auch 
nach 32 Jahren C-Programmierung bin ich immer noch bereit, dazuzulernen 
:-)

Und sag mir bitte, warum Standardfunktionen strncpy(), strncat(), 
snprintf() usw. alle so arbeiten wie ich und nicht so, wie Du? Waren das 
alles Idioten, die die libc geschrieben haben?

Autor: Joe F. (easylife)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
user schrieb:
> Hallo, auf einem Mikrocontrollersystem
(...)

in Anbetracht dessen, werfe ich mal eine schmale Lösung ganz ohne printf 
in die Runde.
In solchen Umgebungen sollte der Programmierer natürlich genau wissen, 
was er tut (meine Meinung). Spart Ausführungszeit und Speicherplatz.
void convert(char *buf, unsigned int addr)
{
  unsigned char d;
  int i;
  
  for (i=0; i<4; i++)
  {
    d = addr >> 24;

    if (d>=100) {
      *buf++ = '0' + d/100;
      d %= 100;
    }

    if (d>=10) {
      *buf++ = '0' + d/10;
      d %= 10;
    }
    
    *buf++ = '0' + d;
    *buf++ = '.';
    
    addr <<= 8;
  }
  *--buf=0;
}

Autor: Peter II (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Joe F. schrieb:
> Spart Ausführungszeit und Speicherplatz.

nicht wirklich. Auf Atmels die nicht sinnvoll shiften und dividieren 
können ist der code sehr ungünstig.
 d = addr >> 24;
 addr <<= 8;
 d/10;
 d %= 10;

Autor: Bernd B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe es nicht ausprobiert, aber ich wage trotzdem zu bezweifeln, 
dass das bei printf() besser wäre.

Autor: Peter D. (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Spart aber nur Code, wenn im gesamten Programm kein printf benutzt wird.

Autor: Mikro 7. (mikro77)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Offensichtlich haben wir unterschiedliche "Aufassungen".

Frank M. schrieb:
> Man will in diesem Beispiel chars modifizieren, also übergibt man
> einen Pointer drauf, das wäre also (char *).

Nein. Es soll ein char Array modifiziert werden.

Mikro 7. schrieb:
> char s1[16] ;

Also wird ein Zeiger darauf übergeben.

Mikro 7. schrieb:
> convert(i1,&s1) ;

> Du übergibst aber einen
> Pointer auf ein ganzes Array, also eine Dimension mehr, als nötig ist.

Es wird die Adresse von s1 übergeben. (Wie übergibt man eine zusätzliche 
Dimensionen von s1?)

> Übergibst Du auch (int **), wenn Du lediglich ints modifizieren willst?

Nein. Du?

Ich würde int(*)[] übergeben. Das ist was anderes als (int**). (So 
langsame vermute ich was du hier als Dimension mißverstehst.)

> Dein Beispiel schützt (bedingt) vor 2, aber nicht vor 1.

Es gibt einen Kontrakt zwischen Aufrufer und Aufgerufenen. Eine Funktion 
muss ihre Zusage einhalten. Wenn du dem nicht zustimmst, können wir an 
diesem Punkt die Diskussion einstellen.

> Mein Beispiel, das wesentlich simpler gestrickt ist und deshalb auch von
> einem fortgeschrittenen Anfänger verstanden wird, deckt beide Punkte ab.

Und ich habe auch zugestimmt, dass man da so machen kann (und meist so 
gemacht wird). Der Rest ist... Spekulation.

> Wenn Du auch diese Argumentation ablehnst, dann sag mir bitte, was an
> meiner einfacheren Lösung schlechter ist als an Deiner komplexeren.

Nee... Du machst schon wieder Spass?!

Deine Lösung ist von Laufzeit, Quelltext und Zielcode komplexer. Dafür 
ist sie aber auch genereller.

Mein Beispiel erscheint dir vielleicht komplexer, weil du möglicherweise 
(wie imho die meisten C Programmierer) nicht gewohnt bist, mit Pointer 
auf Arrays zu arbeiten.

> Auch
> nach 32 Jahren C-Programmierung bin ich immer noch bereit, dazuzulernen
> :-)

Finde ich gut.

> Und sag mir bitte, warum Standardfunktionen strncpy(), strncat(),
> snprintf() usw. alle so arbeiten wie ich und nicht so, wie Du? Waren das
> alles Idioten, die die libc geschrieben haben?

Deine Argumentation ist also: "Weil ich nicht weißt warum das so ist, 
kann es nicht (gut) sein." Daran müssen wir noch arbeiten. ;-)

Na gut, hier ein Grund: Auch wenn sie wollten könnten sie es nicht, weil 
die Arraygröße (wie bereits oben gesagt) zur Laufzeit nicht mehr 
vorhanden ist. Man könnte es mit Makros lösen. In C++ kann man es mit 
Templates lösen.

Als Schlusspunkt (für mich ist er das auf jeden Fall): Ein Pointer auf 
ein Array ist eine Möglichkeit, nich passende Buffer zur Compilezeit 
zu entdecken. Das funktioniert nur in bestimmten Situationen (fixes 
Array) und ist kein Allheilmittel. Der Programmierer muss wissen 
ob/wann/wie er diese Möglichkeit nutzt.

Schönes Wochende!

Autor: Frank M. (ukw) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mikro 7. schrieb:
> Mein Beispiel erscheint dir vielleicht komplexer, weil du möglicherweise
> (wie imho die meisten C Programmierer) nicht gewohnt bist, mit Pointer
> auf Arrays zu arbeiten.

Nur als letztes Wort: An diesem Satz habe ich verstanden, dass Du zu 
flüchtig liest.

Beispiele:

Frank M. schrieb:
> Ich habe da kein Problem, ich arbeite teilweise mit drei oder gar vier
> Sternchen in Funktionsparametern ;-)

Was hast Du "drei oder gar vier Sternchen" nicht verstanden? Ich bin mit 
zum Beispiel mit (struct foo ** bar[i]) auf Du und Du. Das ist mein 
täglich Brot.

Frank M. schrieb:
> Ich sehe das Problem eher beim TO, dessen Wissensstand man ganz gut
> abschätzen kann.

Warum beziehst Du diesen Satz auf mich, wenn ich explizit sage, dass es 
zu komplex für den TO ist, ich selbst aber kein Problem damit habe?

Antwort:

Du liest nur quer, aber schießt wild um Dich. Das zeugt von mangelndem 
Respekt gegenüber Deinem Leser.

Du hast auch nicht verstanden, dass Deine Lösung, ein Array als 
Parameter konkret in der Länge anzugegben und auch nur konkret exakt so 
zu erlauben, eine Speziallösung ist, die meist nicht praxistauglich ist. 
Für eine lib wäre sie sogar untauglich.

Würdest Du jetzt für jede erdenkliche Array-Größe eine eigene 
strcpy-Funktion schreiben, damit Du die Länge exakt in der Form [16] 
angeben kannst? Da hättest Du aber eine zeitlang zu tun. ;-)

Immerhin hast Du dynamische Allokation schon selbst angesprochen. Da ist 
schon Ende im Schacht und Du kannst Deine Lösung in die Tonne treten.

Aber egal, was Du von mir denkst. Du behandelst Deine Leser von oben 
herab und daher bist Du kein adäquater Gesprächspartner für mich.

Daher: Bye :-)

: Bearbeitet durch Moderator
Autor: Joachim B. (jar)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Mikro 7. schrieb:
> --Anstatt einen Kommentar zu schreiben, dass der Aufrufer einen 16-Byte
> Puffer zur Verfügung stellen muss, kann man das auch im Funktionskopf
> definieren.
> #include <stdio.h>
> #include <stdint.h>
>
> void convert(uint32_t i,char(*buffer)[16])

soll die 16 für den Sting sein, 4 Byte a 3 Stellen + '.'?

wo ist die Terminierungs NULL, ich glaube SO werde ich C nie verstehen.

ich brauch 16 + 1 Zeichen, macht für mich buffer[17] mit char von 
buffer[0] - buffer[15] und Terminierung auf buffer[16]=0;

und das geht nur bis IVP4 später mit IVP6 kracht es wieder

Autor: Joe F. (easylife)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Joachim B. schrieb:
> ich glaube SO werde ich C nie verstehen.

Es sind nur 3 Punkte... ;-)

Autor: guest (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Joachim B. schrieb:
> soll die 16 für den Sting sein, 4 Byte a 3 Stellen + '.'?
>
> wo ist die Terminierungs NULL, ich glaube SO werde ich C nie verstehen.
>
> ich brauch 16 + 1 Zeichen, macht für mich buffer[17] mit char von
> buffer[0] - buffer[15] und Terminierung auf buffer[16]=0;

Rechnen und Lesen will gelernt sein. Hier hats jemand schon 
vorgerechnet:
Beitrag "Re: Konvertierung unsigned int --> unsigned char*"

Autor: Joachim B. (jar)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
guest schrieb:
> Rechnen und Lesen will gelernt sein. Hier hats jemand schon
> vorgerechnet:

arg.......

dem letzten Byte fehlt ja der Punkt, wird durch NULL ersetzt

macht 16 Zeichen, OK OK ich sehe es ein, ich ging von 4 x 4 + NULL aus

Ist warm hier und meine grauen Zellen sind auch schon alt.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.