Forum: PC-Programmierung Structure Variable in C


von Stefan (Gast)


Lesenswert?

Ich möchte gerne aus einer Structure z.B.

typedef struct
{
char MX1 [4];
char MX2 [4];
char HY1 [3];
} UMM;

Nun meine Frage ist es möglich, dass ich aus dieser Structure einen 
String machen kann, und dies möglichst einfach. Meine Idee wäre:

String=sprintf(char; UMM[0-12]);

Oder so in dieser Art ich möchte es einfach vermeiden dass ich den 
String aus den einzelnen Bytes zusammensetzen muss.

Entschuldigt wenn der Code nicht ganz einwandfrei ist, ich habe noch 
etwas probleme mit  C Programmieren.

Freundliche Grüsse Stefan

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

> Oder so in dieser Art ich möchte es einfach vermeiden dass ich den
> String aus den einzelnen Bytes zusammensetzen muss.

Ist jedes einzelne Byte ein darstellbares Zeichen?

Dann ginge das so:
1
printf("%c%c%c%c ", u.MX1[0], u.MX1[1], u.MX1[2], u.MX1[3]);

Ist ein Krampf im Arsch.

Also scheint ein Zusammenkopieren doch sinnvoller:
1
#define LEN 12   // zwei Teilstrings à vier und 
2
                 // einer à drei Zeichen 
3
                 // und Nullterminator
4
5
char string[LEN]; 
6
7
memcpy(string, u.MX1, 4);
8
memcpy(string + 4, u.MX2, 4);
9
memcpy(string + 8, u.HY1, 3);
10
11
string[11] = '\0';

von Karl H. (kbuchegg)


Lesenswert?

Die Frage ist so ohne weitere Infos nicht besonders gut beantwortbar.

Was steht in den einzelnen MX1, MX2, HY1 drinnen?
Sind das selbst Strings oder irgendwelche andere Werte.

Wozu brauchst du den Ergebnisstring? Muss das Ergebnis ein String sein, 
oder brauchst du nur eine Bytesequenz, die du zb. über eine serielle 
Schnittstelle verschicken kannst (um sie an der Gegenstelle wieder 
aufzudröseln).

Je nach den Details kann eine vernünftige Antwort von einer 
strcpy/strcat Sequenz bis hin zu einem simplen cast reichen.

von Stefan (Gast)


Lesenswert?

Ahh ok ja jedes Byte ist ein darsellbares Zeichen.

Nun dann werde ich es wohl doch zusammenkopieren müssen.

Vielen dank für die Rasche und Informative Antwort Rufus.

Freundliche Grüsse Stefan

von Stefan (Gast)


Lesenswert?

@ Karl

Also in den Einzelnen MX1, MX2 usw. stehen die werte von bis zu 32 
Relays die über ein GUI gesetzt werden. Diese Werte muss ich dann in 
ASCII in dem String an einen uP schicken.

Ich hoffe das klärt das ganze etwas.

von Rainer I. (raih)


Lesenswert?

Man könnte de struktur als char pointer casten.
1
#define LEN 12   // 11 char + Nullterminator !!
2
3
char string[LEN]; 
4
5
memcpy(string, (char*)&u, 11);
6
string[11] = '\0';

von guest (Gast)


Lesenswert?

wenn dann alles mit dem define... ;-)
1
#define LEN 13   // 12 char + Nullterminator !!
2
3
char string[LEN]; 
4
5
memcpy(string, (char*)&u, (LEN-1));
6
string[(LEN-1)] = '\0';

von Stefan (Gast)


Lesenswert?

Nun habe ich noch ein anderes Problem, ich muss die char Werte von der 
Structure in ASCII Zeichen Umwandeln und diese dann im String einbinden. 
Gibt es eigentlich einen Platzhalter der dies macht, so wie z.B. %c für 
char oder wie muss ich das machen?

von tuppes (Gast)


Lesenswert?

Und was ist, wenn eins der Datenbytes 0 ist? Nach der Beschreibung 
"...stehen die werte von bis zu 32 Relays..." ist das durchaus nicht 
ausgeschlossen. Dann erlebt derjenige, der das Ding annimmt und als 
"String" interpretiert, eine Überraschung.

Dass man ein paar Bytes nacheinander in einen zusammenhängenden 
Speicherbereich kopiert, macht diese Bytes noch nicht zu einem String. 
Man sollte sich zur Angewohnheit machen, nicht nur syntaktisch, sondern 
auch semantisch richtig zu programmieren.

von Rainer I. (raih)


Lesenswert?

Hallo Stefan,

weiter oben schreibst Du, daß es darstellbare Zeichen sind.

Stefan wrote: "Ahh ok ja jedes Byte ist ein darsellbares Zeichen."

Jetzt schreibst Du, daß Du sie erst in ASCII umwandeln musst.
Welchen Zeichen stehen denn jetzt in der Struktur ??

von P. S. (Gast)


Lesenswert?


von Karl H. (kbuchegg)


Lesenswert?

Ich vermute mal, dass

   char MX[4];


dazu gedacht ist, mit jeweils einem Bit den Zustand eines Relais 
anzuzeigen. Ist aber eine reine Vermutung

Die nächste Fragestellung, die sich mir stellt: In welcher Weise kommt 
da jetzt ASCII ins Spiel? Also: Worum gehts es denn überhaupt? Geht es 
darum einem anderen µC die Relaisbelegung zu übermitteln, dann ist der 
Umweg über einen String sowieso Overkill. Einfach die 4 Bytes 
hintereinander senden und gut ists. Geht es darum, einem menschlichen 
Benutzer eine Übersicht über die Relais zu verschaffen, dann wird man 
mit Sicherheit nicht damit glücklich sein, dem einfach die Bytes 
vorzuwerfen, sondern man muss tatsächlich einen vernünftigen String 
daraus zusammenbauen, wobei es wieder davon abhängt, wieviel Komfort man 
dem Benutzer zugesteht.

Ich glaube herausgelesen zu haben, dass ersteres gewünscht wird (also 
eine reine Übertragung der Bytes). Aber das glaube ich nur, ich bin mir 
nicht 100% sicher.
Ich glaube auch, dass das Problem des TO darin besteht, dass er zwar 
eine Funktion hat, die einen String versenden kann und keine die eine 
bestimmte Anzahl an Bytes akzeptiert. Jetzt versucht er sein Problem 
damit zu lösen, dass er die Struktur auf Biegen und Brechen in einen 
String verwandelt, wenn die Lösung eigentlich darin bestehen würde, sich 
eine Sende/Empfangsfunktion zu schreiben, die einfach nur eine bestimmte 
Anzahl an Bytes durch die Gegend schickt.

von Stefan (Gast)


Lesenswert?

Nun ich glaub dass ich es zuerst wohl falsch verstanden haben, also in 
der Structur welche die Werte der Relays geschrieben/gespeichert werden 
steht ein Byte für 8 Relays (hex). Dieser Wert muss ich nun für den 
String in ASCII Zeichen Umwandeln und dieser dann via USB an einen 
uP-Print schicken.

So steht es auf jeden Fall im Pflichtenheft nach dem ich Arbeite. Nun 
weiss ich nicht wie ich das am einfachsten lösen kann.

von Karl H. (kbuchegg)


Lesenswert?

Stefan wrote:
> Nun ich glaub dass ich es zuerst wohl falsch verstanden haben, also in
> der Structur welche die Werte der Relays geschrieben/gespeichert werden
> steht ein Byte für 8 Relays (hex). Dieser Wert muss ich nun für den
> String in ASCII Zeichen Umwandeln

Wie muss dieser String aussehen?

Deine Bytes kannst du nicht einfach als ASCII Zeichen auffassen und 
übertragen. Damit erleidest du Schiffbruch.

Da muss also mindestens mal eine Umwandlung rein, die wahrscheinlich die 
einzelnen Bits aufdröselt.

Anders gefragt: Welchen String erwartet denn die uP-Print? Kannst du mal 
ein Beispiel zeigen?
Angenommen deine 4 Bytes in MX sehen so aus

    0x00 0xF8 0x32 0x56

welchen String (=Text) will die uP-Print sehen, um daraus sich die 
korrekte Belegung zu generieren (Was immer auch ein uP-Print ist)

von Peter (Gast)


Lesenswert?

Die Frage ist was mit ASCII String gemeint ist, laut ASCII können es 
immerhin 127 Zeichen sein - die Zwar nicht alle Lesbar sind aber das ist 
dem Computer egal.

von Stefan (Gast)


Lesenswert?

Also nach Vorgabe muss der String mit ("Start","Stop") als grenze 
definiert sein und die Daten als String/Text gesendet werden.

Wenn ich das richtig verstehe sollte dann der String ungefähr so 
aussehen:

StartxF1x00xA0xStop wobei die "x" als Abtrennung zwischen den einzelnen 
Werte fungieren.

Und die "F1" "00" usw. muss ich als ASCII einbinden.

von Karl H. (kbuchegg)


Lesenswert?

Stefan wrote:
> Also nach Vorgabe muss der String mit ("Start","Stop") als grenze
> definiert sein und die Daten als String/Text gesendet werden.
>
> Wenn ich das richtig verstehe sollte dann der String ungefähr so
> aussehen:

Nicht ungefähr.
Du musst dir sicher sein!

Du kannst erst dann eine korrekte Ausgabe erzeugen, wenn du weißt was du 
überhaupt erzeugen musst. Manchmal macht man erst mal Vorstudien, indem 
man zb ein Terminal an das Ausgabegerät hängt und einfach mal als 
menschlicher Computer mit dem Endgerät 'spielt' um rauszufinden welchen 
String man tatsächlich schicken muss.

> StartxF1x00xA0xStop wobei die "x" als Abtrennung zwischen den einzelnen
> Werte fungieren.

OK.
1
  char buffer[30];
2
  sprintf( buffer, "Startx%02xx%02xx%02xx%02xxStop", UMM.MX1[0], UMM.MX1[1], UMM.MX1[2], UMM.MX1[3] );

würde zb. so einen String nach dieser Vorgabe zusammenbauen.

Man könnte es aber auch so machen
1
  char buffer[80];
2
  char tmp[10];
3
4
  strcpy( buffer, "Start" );
5
  for( i = 0; i < 4; ++i ) {
6
    sprintf( tmp, "x%02x", UMM.MX1[i] );
7
    strcat( buffer, tmp );
8
  }
9
10
  strcat( buffer, "xEnd" );

Oder beliebige andere Variationen davon.

von Peter (Gast)


Lesenswert?

naja wenn jetzt sogar trennzeichen gebaucht werden dann wirst du wohl 
nicht ringsrumkommen eine funktion für das Senden der Struktur zu 
schreiben.

von Karl H. (kbuchegg)


Lesenswert?

Ooops. Fehler meinerseits.

In deinem Vorgabestring waren die Buchstaben für die Hex-Ziffern 
Grossbuchstaben. Also muss im Format-String für sprintf dafür ein 
grosses X benutzt werden
1
  sprintf( buffer, "Startx%02Xx%02Xx%02Xx%02XxStop", UMM.MX1[0], UMM.MX1[1], UMM.MX1[2], UMM.MX1[3] );

von Stefan (Gast)


Lesenswert?

@karl vielen dank, ich habe mal schnell deine Variante in einem Programm 
getestet und es ist genau das was ich gesucht habe. Einfach genial, ich 
wäre wohl noch lange nicht darauf gekommen.

Ich danke euch allen für die tolle Hilfe, Ihr habt mir sehr geholfen.

Freundliche Grüsse Stefan

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.