structs incrementieren?

OP #5325358
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
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
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
Ich denke so:

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

const DevBoard_t uartMsg;

const char *ptr = &uartMsg;
Gast
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
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?
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
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
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
}
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
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
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.
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

Eine eigene Frage? Dieser Thread ist über 8 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.