Structure Variable in C

Gast #1196102
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
Persönliche Seite #1196113
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';
#1196118
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.
Gast #1196128
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.
Gast #1196212
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?
Gast #1196219
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.
#1196317
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.
Gast #1196322
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.
#1196329
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)
Gast #1196340
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.
#1196346
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.
#1196368
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] );
Gast #1196376
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren