structs incrementieren?

OP #5325358
Lesenswert?

1
typedef struct
2
{
3
  const char *projectName;
4
  const char *hardwareDate;
5
  const char *madeBy;  
6
}DevBoard_t;
7

8
const DevBoard_t *uartMsg = &Message;


Ist es irgendwie möglich auf die einzelnen Strings in dieser Struktur 
via. increment zu kommen?
1
for (uint8_t i = 0 ; i < 3 ; i++)
2
{
3
  uart_puts((char*)(uartMsg++));
4
        uart_puts("\r\n");
5
}
Gast #5325372
Lesenswert?

Du hast den Struct als Zeiger definiert. Ist das richtig?

Ich wäre so vorgegangen. Den Struct ganz "normal" als Variable, kein 
Zeiger, definiert.
Dann einen pointer, der auf die Anfangsadresse des Structs zeigt 
definiert.
Wenn man dann den pointer incrementiert, müsste er auf das nächste 
Element zeigen.
OP #5325375
Lesenswert?

Teddy schrieb:
> Du hast den Struct als Zeiger definiert. Ist das richtig?
>
> Ich wäre so vorgegangen. Den Struct ganz "normal" als Variable, kein
> Zeiger, definiert.
> Dann einen pointer, der auf die Anfangsadresse des Structs zeigt
> definiert.
> Wenn man dann den pointer incrementiert, müsste er auf das nächste
> Element zeigen.

Genau so habe Ich das getan. Das klappt eben nicht..
Gast #5325382
Lesenswert?

ist IMHO undefiniertes Verhalten, aber wenn du Dich darauf verlässt dass 
die Element in der gleichen Reihenfolge und ohne padding hintereinander 
im Speicher liegen und der Anfang des structs identisch mit seinem 
ersten element ist, dann sollte es gehen.

Wenn der struct aber ehe nur die gleichen Element-typen (const char *) 
beinhaltet solltest Du einfach ein array nutzen, dann klappts auch mit 
der pointer-arithmetic :-)
OP #5325385
Lesenswert?

micha schrieb:
> ist IMHO undefiniertes Verhalten, aber wenn du Dich darauf
> verlässt dass
> die Element in der gleichen Reihenfolge und ohne padding hintereinander
> im Speicher liegen und der Anfang des structs identisch mit seinem
> ersten element ist, dann sollte es gehen.
>
> Wenn der struct aber ehe nur die gleichen Element-typen (const char *)
> beinhaltet solltest Du einfach ein array nutzen, dann klappts auch mit
> der pointer-arithmetic :-)

Wie würde das denn dann aussehen?
1
union test
2
{
3
  DevBoard_t Message;
4
  char uartMsg[];
5
};
So ungefähr?
#5325406
Lesenswert?

Jan H. schrieb:
> micha schrieb:
>> ist IMHO undefiniertes Verhalten, aber wenn du Dich darauf
>> verlässt dass
>> die Element in der gleichen Reihenfolge und ohne padding hintereinander
>> im Speicher liegen und der Anfang des structs identisch mit seinem
>> ersten element ist, dann sollte es gehen.
>>
>> Wenn der struct aber ehe nur die gleichen Element-typen (const char *)
>> beinhaltet solltest Du einfach ein array nutzen, dann klappts auch mit
>> der pointer-arithmetic :-)
>
> Wie würde das denn dann aussehen?
>
1
> union test
2
> {
3
>   DevBoard_t Message;
4
>   char uartMsg[];
5
> };
6
>
> So ungefähr?

Wenn die einzelnen C-Strings in DevBoard_t 0-terminated sind (wie es bei 
C-Strings angenommen wird), dann wird nur der erste String in DevBoard_t 
ausgegeben.

Edit: Sehe gerade, dass die Elemente in DecBoard_t gar keine char-Arrays 
sind, dann geht das natürlich so eh nicht.

Warum gibst Du die C-Strings nicht einfach direkt aus, statt so ein 
type-punning einzubauen (was zugegebenermaßen in C erlaubt und kein UB 
ist).
Gast #5325412
Lesenswert?

Jan H. schrieb:
> typedef struct
> {
>   const char *projectName;
>   const char *hardwareDate;
>   const char *madeBy;
> }DevBoard_t;
>
> const DevBoard_t *uartMsg = &Message;
>
> Ist es irgendwie möglich auf die einzelnen Strings in dieser Struktur
> via. increment zu kommen?for (uint8_t i = 0 ; i < 3 ; i++)
> {
>   uart_puts((char*)(uartMsg++));
>         uart_puts("\r\n");
> }

typedef struct {
    const char *projectName;
    const char *hardwareDate;
    const char *madeBy;
} DevBoard_t;

char** test = ()
Persönliche Seite #5325422
Lesenswert?

Jan H. schrieb:
> Ist es irgendwie möglich auf die einzelnen Strings in dieser Struktur
> via. increment zu kommen?

Vielleicht ein Array mit benamten Indices anstatt Komponenten?  Eine 
Union wie oben genannt geht zwar auch, aber die Lesbarkeit solcher 
Konstrukte ist nicht sooo toll.

Beispiel:
1
enum
2
{
3
    ID_ProjectName,
4
    ID_HardwareDate,
5
    ID_MadeBy,
6
    ID_Count
7
};
8

9
typedef struct
10
{
11
  const char *strings[ID_Count];
12
} DevBoard_t;
13

14
const DevBoard_t Message =
15
{
16
    {
17
        [ID_ProjectName] = "Project",
18
        [ID_HardwareDate] = "Now",
19
        [ID_MadeBy] = "Me"
20
    }
21
};
22

23
const DevBoard_t *uartMsg = &Message;
24
extern void uart_puts (const char*);
25

26
void func (const DevBoard_t *board)
27
{
28
    for (int i = 0; i < ID_Count; i++)
29
    {
30
        uart_puts (board->strings[i]);
31
    }
32
    
33
    const char *const *str = board->strings;
34

35
    for (int i = 0; i < ID_Count; i++)
36
    {
37
        uart_puts (*str++);
38
    }
39
}
#5325433
Lesenswert?

Etwa so:
1
typedef struct {
2
  const char *projectName;
3
  const char *hardwareDate;
4
  const char *madeBy;  
5
} DevBoard_t;
6

7
typedef union {
8
    DevBoard_t db;
9
    const char* array[3];
10
} Strings;
11

12
int main() {
13
    DevBoard_t db = {"abc", "def", "ghi"};
14
    Strings s = {db};
15

16
    printf("n: %s\n", s.array[0]);    
17
    printf("h: %s\n", s.array[1]);    
18
    printf("m: %s\n", s.array[2]);    
19
    
20
    const char** ptr = s.array;
21

22
    printf("n: %s\n", *ptr++);    
23
    printf("h: %s\n", *ptr++);    
24
    printf("m: %s\n", *ptr);    
25
}

Aber gut ist das nicht.

Besser schreibst Du eine eigene Funktion (in C) oder überlädst (in C++) 
eine entsprechende Ausgabefunktion.
OP #5325453
Lesenswert?

Johann L. schrieb:
> Beispiel:
> enum
> {
>     ID_ProjectName,
>     ID_HardwareDate,
>     ID_MadeBy,
>     ID_Count
> };
>
> typedef struct
> {
>   const char *strings[ID_Count];
> } DevBoard_t;
>
> const DevBoard_t Message =
> {
>     {
>         [ID_ProjectName] = "Project",
>         [ID_HardwareDate] = "Now",
>         [ID_MadeBy] = "Me"
>     }
> };
Diese Lösung finde ich recht interessant.
Wie sieht es mit einem "String Array" aus? Kann Ich das da auch so 
einfach einbinden?
1
     char *name[x];
Persönliche Seite #5325583
Lesenswert?

Jan H. schrieb:
> Diese Lösung finde ich recht interessant.
> Wie sieht es mit einem "String Array" aus? Kann Ich das da auch so
> einfach einbinden?

Das kommt auf die Anwendung an ob das besser ist:
1
enum { ... };
2

3
#define MAX_LEN 10
4

5
typedef struct
6
{
7
  const char strings[ID_Count][MAX_LEN];
8
} DevBoard_t;
9

10
const DevBoard_t Message =
11
{
12
    {
13
        [ID_ProjectName] = "Project",
14
        [ID_HardwareDate] = "Now",
15
        [ID_MadeBy] = "Me"
16
    }
17
};
18

19
extern void uart_puts (const char*);
20

21
const DevBoard_t *uartMsg = &Message;
22

23
void func (const DevBoard_t *board)
24
{
25
    for (int i = 0; i < ID_Count; i++)
26
    {
27
        uart_puts (board->strings[i]);
28
    }
29
    
30
    const char (*str)[MAX_LEN] = board->strings;
31

32
    for (int i = 0; i < ID_Count; i++)
33
    {
34
        uart_puts (*str++);
35
    }
36
}

Ein Problem ist, dass die maximale String-Länge statisch bekannt sein 
muss. Und während man ein const char* ändern und auf einen anderen 
String zeigen lassen kann, ist das bei einem const char[] nicht so.  Und 
ohne das "const" brauch man ein strcpy um einen neuen String 
hineinzubekommen.  Dafür brauch man beim Zugriff eine Indirektion 
weniger und keinen Platz zum Speichern der Adressen, allerdings gibt es 
auch Verschnitt bei ungleich langen Strings.
#5325619
Lesenswert?

Ich denke hier wäre ein Array angebrachter. Beispiel:
http://rextester.com/NUW57351
1
#include <stdio.h>
2

3
#define DEVBOARD_INFO \
4
  X(PROJECT_NAME, "Name des Projekts") \
5
  X(HARDWARE_DATE, "Herstelldatum des Geräts") \
6
  X(MADE_BY, "Hergestellt von")
7

8
enum devboard_entries {
9
#define X(N,D) DEVBOARD_INFO_ ## N,
10
DEVBOARD_INFO
11
#undef X
12
DEVBOARD_INFO_COUNT
13
};
14

15
const char* devboard_info_description[] = {
16
#define X(N,D) D,
17
DEVBOARD_INFO
18
#undef X
19
};
20

21
typedef const char* devboard_info_t[DEVBOARD_INFO_COUNT];
22

23
devboard_info_t devboard = {
24
  [DEVBOARD_INFO_PROJECT_NAME] = "Mein Projekt",
25
  [DEVBOARD_INFO_HARDWARE_DATE] = "1970-1-1",
26
  [DEVBOARD_INFO_MADE_BY] = "mir",
27
};
28

29
void print_devboard_info(devboard_info_t info){
30
  for( int i=0; i<DEVBOARD_INFO_COUNT; i++ ){
31
    printf("%s: %s\n", devboard_info_description[i], info[i]);
32
  }
33
}
34

35
int main(){
36
  print_devboard_info(devboard);
37
}

Edit: war mal wieder zu spät...

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