www.mikrocontroller.net

Forum: GCC Struktinhalt ohne Komponentenname ansprechen

Autor: Christoph O. (ozzy)
Datum: 02.05.2008 14:52

Hi,

ist es möglich, Inhalte eines structs über eine Schleife anzusprechen,
und nicht über die Komponentennamen? Also nicht struct1.name sondern
irgendwas mit "i++"???

MfG, und vielen Dank, Ozzy
Autor: Oliver (Gast)
Datum: 02.05.2008 14:58

"Einmal Döner, aber bitte ohne Brot, Zaziki, Fleisch, Salat, und
Sosse..."

Wofür baut man sich einen struct, wenn gar keiner gewünscht wird?

Beitrag "Datenzuweisung an Struct"

Oliver
Autor: Stan (Gast)
Datum: 02.05.2008 15:28

Was möchtest Du machen?
Autor: Christoph O. (ozzy)
Datum: 02.05.2008 15:56

Hi,

also ich bekomme Daten über die serielle Schnittstelle. Es handelt sich
dabei um einen String in dem Werte stehen, durch "," getrennt. Manchmal
fehlen diese Werte aber, so dass meherere Kommata hintereinander stehen:
"500,10.00,,20,1,,,W,17". Nun habe ich ein paar Zeilen geschrieben, die
mir diesen String an den entsprechenden Stellen auseinandernehmen
(strtok_r gibt ja leider nicht an, wenn meherer Trennzeichen
hintereinander stehen...).
Damit meine Funktion nun aber schön darauf arbeiten kann, wollte ich ein
schönes Struct daraus machen. Klar, Array ginge wohl auch, aber die
anderen Funktionen könnten wieder auf den Komponentennamen zugreifen,
was die Lesbarkeit des Codes erhöhen würde...

MfG, Ozzy
Autor: Werner B. (Gast)
Datum: 02.05.2008 15:58

Stichwort: "union".
Autor: Karl heinz Buchegger (kbuchegg) (Moderator)
Datum: 02.05.2008 16:04

Christoph O. wrote:

> "500,10.00,,20,1,,,W,17". Nun habe ich ein paar Zeilen geschrieben, die
> mir diesen String an den entsprechenden Stellen auseinandernehmen
> (strtok_r gibt ja leider nicht an, wenn meherer Trennzeichen
> hintereinander stehen...).
> Damit meine Funktion nun aber schön darauf arbeiten kann, wollte ich ein
> schönes Struct daraus machen.

Ich seh ehrlich gesagt nicht, wie dir da ein alternativer Zugriff
auf die Struktur helfen würde. Aus dem Pointer, den dir strtok_r
zurückgibt kannst du sowieso keinen Rückschluss darauf ziehen,
wieviele ',' strtok_r nun überlesen hat. OK. 'keinen' stimmt nicht
ganz, aber mühsam bleibt es trotzdem.

Ich würde die Parsing Funktion verändern bzw. mir ein eigenes
strtok_r schreiben, welches dieses Problem nicht hat.
Autor: Christoph O. (ozzy)
Datum: 05.05.2008 09:18

Hi,

   also ich habe mir auch so eine Funktion geschrieben, die mir die
Kommata zählt, indem ich einfach bei strtok_r den dritten Paramtere
&last auswertet, und schaut, ob da ein Komma steht, und wenn ja,
wieviele...
   Da das aber in einer Schleife geschieht, bis der String zu ende ist,
komme ich nicht so schön an die Komponenten ran.

   Wie das mit union gehen soll, habe ich nicht so wirklich
verstanden...

   MfG, Ozzy
Autor: Karl heinz Buchegger (kbuchegg) (Moderator)
Datum: 05.05.2008 10:20

Christoph O. wrote:

>    Wie das mit union gehen soll, habe ich nicht so wirklich
> verstanden...

Ich ehrlich gesagt auch nicht.

Ich steh immer noch dazu, dass eine spezielle strtok_r Verison
die einfachste Variante ist. Die Funktion ist so schwer nun
auch wieder nicht
#include <stdio.h>

char* split( char* string, char character, char** end )
{
  if( string != NULL )
    *end = string;
  else
    string = *end;

  if( **end == '\0' )
    return NULL;

  while( **end != '\0' &&
         **end != character )
    (*end)++;

  if( **end == '\0' )
    return string;

  **end = '\0';
  (*end)++;

  return string;
}

int main()
{
  char Str[] = ",Arg1,Arg2,,Arg4";
  
  char* pTmp;
  char* pArg;

  pArg = split( Str, ',', &pTmp );
  while( pArg ) {
    printf( "> /%s/\n", pArg );
    pArg = split( NULL, ',', &pTmp );
  }
}
Autor: Hans (Gast)
Datum: 05.05.2008 10:32

Nur so als Hintergrund:

Das Thema heißt "Objektrelationale Abbildung" oder "Objektrelationales
Mapping". Ein Objekt (hier struct) wird auf eine relationale Struktur
(hier die Kommaliste) abgebildet.

Hier ein entsprechendes Framework einzusetzen, wäre allerdings mit
Kanonen auf Spatzen geschossen.
Autor: yalu (Gast)
Datum: 05.05.2008 10:32

@Karl heinz:

Ich glaube, Christoph geht es nicht primär um das Auseinanderfieseln
des Eingabestrings, sondern darum, wie man die auseinandergefieselten
Zahlenwerte in eine entsprechende Struktur eintragen kann, ohne jede
Elementzuweisung einzeln hinzuschreiben. Da das Auseinanderfieseln
(egal ob mit strtok_r oder anders) typischerweise in einer Schleife
stattfindet, wäre ein indizierter Zugriff auf die Strukturelemente
wünschenswert.

@Christoph:

Wenn alle Strukturelemente vom gleichen Typ sind (z.B. int), kannst
du, wie Werner B. schon geschrieben hat, mittels einer Union ein Array
überlagern oder einen Pointer auf die Struktur in einen int-Pointer
umcasten und diesen dann wie ein Array verwenden. Beides ist aber
nicht ganz sauber, weil dabei Annahmen über das Speicherabbild von
Strukturen gemacht werden.

Besser, aber umständlicher wäre es, ein Array mit Pointern auf die
einzelnen Strukturelemente anzulegen. Das Unschöne hierbei ist, dass
bei jeder Änderung der Struktur auch die Array-Initialisierung
angepasst werden muss.

Wenn die Strukturelemente unterschiedlichen Typs sind, bringt ein
Array nicht viel, da es immer nur Elemente eines Typs enthält. Du
bräuchtest dann Fallunterscheidungen in der Auswerteschleife, so dass
du mit wenig mehr Aufwand auch gleich die einzelnen Strukturelemente
ansprechen kannst.
Autor: Matthias Lipinsky (lippy)
Datum: 06.05.2008 11:57

@Karl heinz:

Was ist das:\
Ein Pointer, der auf einen Pointer to char (also auf einen char*)
zeigt??
char* split( char* string, char character, char** end )
                                           ^^^^^^^^^^^
Autor: Karl heinz Buchegger (kbuchegg) (Moderator)
Datum: 06.05.2008 12:14

Matthias Lipinsky wrote:
> @Karl heinz:
>
> Was ist das:\
> Ein Pointer, der auf einen Pointer to char (also auf einen char*)
> zeigt??

Ganz genau.


Machs einfach mit Analogie:
Wenn eine Funktion ein Argument verändern können will,
dann muss der Aufrufer die Adresse (vulgo Pointer) übergeben,
wo die Ursprungsvariable sitzt.

Aufruferseitig, x sei irgendein Datentyp

  x MyVar;

  foo( &MyVar );

und funktionsseitig
void foo( x * Arg )
{
  *Arg = irgendwas;
}

Mach dir klar, das das zb. gilt wenn x für 'int' steht.

Und jetzt setzt du für x einfach char* ein.

Antwort schreiben

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

Wichtige Regeln - erst lesen, dann posten!

  • Suchfunktion und Betreffsuche benutzen - vielleicht gibt es schon einen ähnlichen Beitrag
  • Aussagekräftigen Betreff wählen
  • Im Betreff angeben um welchen Controllertyp es geht (AVR, PIC, ...)
  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang
  • JPEG-Dateien (.jpg) nur für Fotos verwenden, Schaltpläne, Screenshots usw. als PNG oder GIF anhängen

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [pre]vorformatierter Text (z.B. Code in anderen Sprachen)[/pre]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel






webmaster@mikrocontroller.netImpressumWerbung auf Mikrocontroller.net