Forum: PC-Programmierung 2d array in c erste spalte string, zweite spalte uint8


von Frank (Gast)


Lesenswert?

Ich möchte gerne in c einen 2dimensionalen array erstellen, wobei die 
erste spalte strings enthalten soll und die zweite spalte werte

z,B.
["A"][1]
["B"][2]
usw.

aber ich kann ja nur
uint8_t array[][]
oder
char array[][]

beim ersten habe ich aber beides mal uint8 und beim zweiten habe ich 
beides mal char.
geht so etwas in C überhaupt?
in C# gäbe es ja eine liste, mit der das möglich wäre

von Oliver S. (oliverso)


Lesenswert?

struct

Oliver

von Programmiersprachentheaterintendant (Gast)


Lesenswert?

Frank schrieb:
> Ich möchte gerne in c einen 2dimensionalen array erstellen, wobei die
> erste spalte strings enthalten soll und die zweite spalte werte
>
> z,B.
> ["A"][1]
> ["B"][2]
> usw.
>
> aber ich kann ja nur
> uint8_t array[][]
> oder
> char array[][]
>
> beim ersten habe ich aber beides mal uint8 und beim zweiten habe ich
> beides mal char.

Richtig. Wilkommen bei der niederen "Hoch-"Sprache C.

Wenn Du es geordnet anstellst, hast Du immerhin in beiden Feldern mit 
dem selben Index der  korrespondierende String und Zahlenwert.

Die nächste Evoltionsstufe ist dann in der Tat ein Feld von 
Strukturen.

Bei beiden muss jedoch die Umrechnung von Suchstring zu Index als 
Zwischenschritt ausprogrammiert werden. Gute Übung!
Stichwort: "Algorithmen und Datenstrukturen"

Da sowas bereits viele vor dir getan haben, suche und evaluiere eine 
gebrauchsfertige Bibliothek welche dir o.g. Übung durch eine andere 
ablöst.

von cppbert (Gast)


Lesenswert?

Frank schrieb:
> in C# gäbe es ja eine liste, mit der das möglich wäre

Auch nicht ohne struct oder meinst du ein Dictionary?

von Frank (Gast)


Lesenswert?

cppbert schrieb:
> Auch nicht ohne struct oder meinst du ein Dictionary?

Ja, oder ein Dictionary. Ich weiß nicht mehr genau wie es hieß. Weiß 
aber, dass es sowas gab.

Oliver S. schrieb:
> struct
>
> Oliver

oh ja, das hätte mir auch einfallen können.Besten dank.

Doch leider habe ich probleme damit
1
#include <stdint.h>
2
#include <string.h>
3
#include <stdio.h>
4
5
typedef struct
6
{
7
  int16_t jahr;
8
  uint8_t monat;
9
  uint8_t tag;
10
}DATUM;
11
12
typedef struct
13
{
14
  char ereignis[100];
15
  DATUM datum;
16
}CARDS;
17
18
static void init_cards(CARDS *cards[]);
19
20
int main(int argc, char *argv[])
21
{
22
23
  CARDS* cards[5];
24
25
  init_cards(cards);
26
  printf("initialisierung fertig\n\n");
27
28
  for(uint8_t x=0; x<1; x++)
29
  {
30
    printf("%s Jahr: %d   Monat %d   Tag: %d\n", cards[x]->ereignis, cards[x]->datum.jahr, cards[x]->datum.monat, cards[x]->datum.tag);
31
  }
32
  return 0;
33
}
34
35
static void init_cards(CARDS *cards[])
36
{
37
  printf("beginne initialisierung\n\n");
38
  strcpy(cards[0]->ereignis, "A");
39
  cards[0]->datum.jahr = 1;
40
  cards[0]->datum.monat = 1;
41
  cards[0]->datum.tag = 1;
42
43
  strcpy(cards[1]->ereignis, "B");
44
  cards[1]->datum.jahr = 2;
45
  cards[1]->datum.monat = 2;
46
  cards[1]->datum.tag = 2;
47
48
  printf("ende initialisierung\n\n");
49
}

Wenn ich in der Funktion init_cards nur cards[0] beschreibe und cards[1] 
auskommentiere (die anderen kommen dann später noch hinzu), funktioniert 
alles. Aberwenn ich cards[1] beschreiben möchte, stürzt das Programm ab. 
Also es kommt nicht mehr zum printf "ende initialisierung".

Aber warum? ich übergeben doch den ganzen array und dieser ist 5 
Elemente lang.

von Dirk B. (dirkb2)


Lesenswert?

Frank schrieb:
> CARDS* cards[5];

Das sind nicht 5 CARDS sondern ein Zeiger auf 5 Cards.

Kannst mal mit sizeof(CARDS) überprüfen.

von Rolf M. (rmagnus)


Lesenswert?

Frank schrieb:
> Aber warum? ich übergeben doch den ganzen array und dieser ist 5
> Elemente lang.

Ja, aber es handelt sich um 5 Zeiger, die ins Gemüse zeigen 
(uninitialisiert) Und dieses Gemüse versuchst du dann zu beschreiben.

Frank schrieb:
> CARDS* cards[5];

Damit erzeugst du 5 Zeiger auf Karten, aber keine einzige Karte, in 
die du irgendwelche Werte schreiben könntest.

von Dirk B. (dirkb2)


Lesenswert?

Frank schrieb:
> Aber warum? ich übergeben doch den ganzen array

Das geht in C nicht. Es wird die Adresse vom ersten Element übergeben.

von Rolf M. (rmagnus)


Lesenswert?

Dirk B. schrieb:
> Das sind nicht 5 CARDS sondern ein Zeiger auf 5 Cards.

Umgekehrt: Es sind 5 Zeiger auf jeweils eine Card, aber es sind eben nur 
die Zeiger.

von Dirk B. (dirkb2)


Lesenswert?

Rolf M. schrieb:
> Umgekehrt:

Ja. Ich kann es leider nicht mehr löschen.

von Frank (Gast)


Lesenswert?

Guten morgen und erst einmal Danke für die Hinweise.
Zum laufen habe ich es dennoch noch nicht bekommen.
1
#include <stdint.h>
2
#include <string.h>
3
#include <stdio.h>
4
5
typedef struct
6
{
7
  int16_t jahr;
8
  uint8_t monat;
9
  uint8_t tag;
10
}DATUM;
11
12
typedef struct
13
{
14
  char ereignis[100];
15
  DATUM datum;
16
}CARDS;
17
18
static void init_cards(CARDS cards[]);
19
20
int main(int argc, char *argv[])
21
{
22
23
  CARDS cards[5];
24
25
  init_cards(cards);
26
  //init_cards(&cards);
27
  printf("initialisierung fertig\n\n");
28
29
  for(uint8_t x=0; x<1; x++)
30
  {
31
    printf("%s Jahr: %d   Monat %d   Tag: %d\n", cards[x].ereignis, cards[x].datum.jahr, cards[x].datum.monat, cards[x].datum.tag);
32
  }
33
  return 0;
34
}
35
36
static void init_cards(CARDS cards[])
37
{
38
  printf("beginne initialisierung\n\n");
39
  strcpy(cards[0].ereignis, "A");
40
  cards[0].datum.jahr = 1;
41
  cards[0].datum.monat = 1;
42
  cards[0].datum.tag = 1;
43
44
  strcpy(cards[1].ereignis, "B");
45
  cards[1].datum.jahr = 2;
46
  cards[1].datum.monat = 2;
47
  cards[1].datum.tag = 2;
48
49
  printf("ende initialisierung\n\n");
50
}

Das Problem ist immer noch das selbe.

Ist es denn schon die richtige Richtung?

von Rolf M. (rmagnus)


Lesenswert?

Frank schrieb:
> Ist es denn schon die richtige Richtung?

Ja, das sieht besser aus. Ich kann auch keinen Fehler sehen, abgesehen 
davon, dass du nur das erste Element ausgibst:
1
for(uint8_t x=0; x<1; x++)
Nach dem ersten Durchlauf ist x nicht mehr kleiner als 1, also wird die 
Schleife nur genau einmal durchlaufen.

Es funktioniert bei auch ohne Probleme.

: Bearbeitet durch User
von cppbert (Gast)


Lesenswert?

> Ist es denn schon die richtige Richtung?

Wird besser

Mit

sizeof(Cards)/sizeof(Cards[0])

Bekommst du die groesse des Arrays

Und ich wuerde bei der init cards eher Card* (anstatt Cards[]) und int 
Count uebergeben

von cppbert (Gast)


Lesenswert?

CARDS in CARD umbenennen

Und die zugriffe abkuerzen

CARD* card = &cards[x]; // oder cards+x

card->datum.jahr ...

von Frank (Gast)


Lesenswert?

Rolf M. schrieb:
> Nach dem ersten Durchlauf ist x nicht mehr kleiner als 1, also wird die
> Schleife nur genau einmal durchlaufen.

Da hast du recht :). Aber so weit kommt es ja gar nicht. Bekomme also 
noch nicht einmal das erste Element ausgegeben.

cppbert schrieb:
> Und ich wuerde bei der init cards eher Card* (anstatt Cards[]) und int
> Count uebergeben

Ja, das würde ich später auch machen wollen (also zumindest eine länge 
übergeben. Aber zunächst wollte ich so wenig sachen wie möglich. Läuft 
ja mit weniger auch nicht ;)

cppbert schrieb:
> CARDS in CARD umbenennen

OK. JA, wenn man genau überlegt ist das richtig. Ich beschreibe ja nur 
eine Karte im Struct. Vom struct aber mehrere. deswegen dann cards :)

cppbert schrieb:
> CARD* card = &cards[x]; // oder cards+x

Das habe ich nicht ganz verstanden. Wo muss dass denn hin? Bzw. was 
bewirkt das?


Noch einmal besten dank für die Hinweise

von Dirk B. (dirkb2)


Lesenswert?

Frank schrieb:
> Aber so weit kommt es ja gar nicht. Bekomme also
> noch nicht einmal das erste Element ausgegeben.

Welche Ausgabe kommt?
Startest du auch das richtige (neuste) Programm?
Ein
1
puts(__TIME__);
 am Anfang von main() kann da helfen.

: Bearbeitet durch User
von cppbert (Gast)


Lesenswert?

Frank schrieb:
> Das habe ich nicht ganz verstanden. Wo muss dass denn hin? Bzw. was
> bewirkt das?

weniger schreiben, weniger Fehler
1
#define ARRAY_SIZE(ARRAY) (sizeof(ARRAY)/sizeof(ARRAY[0]))
2
3
for(uint8_t x=0; x<ARRAY_SIZE(cards); ++x)
4
{
5
  CARD* card = &cards[x];
6
7
    printf("%s Jahr: %d   Monat %d   Tag: %d\n", card->ereignis, card->datum.jahr, card->datum.monat, card->datum.tag);
8
  }

von cppbert (Gast)


Lesenswert?

Frank schrieb:
> Das habe ich nicht ganz verstanden. Wo muss dass denn hin? Bzw. was
> bewirkt das?

du solltest dur "dringenst" ein C Pointer Tutorial anschauen - damit 
wirst du in C ständig konfrontiert - muss es also können

https://www.tutorialspoint.com/cprogramming/c_pointers.htm

von cppbert (Gast)


Lesenswert?

cppbert schrieb:
> #define ARRAY_SIZE(ARRAY) (sizeof(ARRAY)/sizeof(ARRAY[0]))
>
> for(uint8_t x=0; x<ARRAY_SIZE(cards); ++x)
> {
>   CARD* card = &cards[x];
>
>     printf("%s Jahr: %d   Monat %d   Tag: %d\n", card->ereignis,
> card->datum.jahr, card->datum.monat, card->datum.tag);
>   }

du kanns die Schleifen z.B. auch so schreiben

#define ARRAY_SIZE(ARRAY) (sizeof(ARRAY)/sizeof(ARRAY[0]))

for(CARD* card = &cards[0]; card != &cards[0]+ARRAY_SIZE(cards); ++card)
{
    printf("%s Jahr: %d   Monat %d   Tag: %d\n", card->ereignis, 
card->datum.jahr, card->datum.monat, card->datum.tag);
  }

sehr viele Wege führen in C nach Rom - und es ist gut die Varianten zu 
verstehen, damit man weniger Fehler macht, schneller ist

von cppbert (Gast)


Lesenswert?

cppbert schrieb:

totaler Quatsch - sorry
1
for(CARD* card = cards; card != cards+ARRAY_SIZE(cards); ++card)
2
{
3
    printf("%s Jahr: %d   Monat %d   Tag: %d\n", card->ereignis,
4
card->datum.jahr, card->datum.monat, card->datum.tag);
5
}

oder auch
1
CARD* begin = &cards[0] // oder einfach cards;
2
CARD* end = begin+ARRAY_SIZE(cards);
3
4
for(card = begin; card != end; ++card)
5
{
6
  printf("%s Jahr: %d   Monat %d   Tag: %d\n", card->ereignis,
7
  card->datum.jahr, card->datum.monat, card->datum.tag);
8
}

von Rolf M. (rmagnus)


Lesenswert?

cppbert schrieb:
> Frank schrieb:
>> Das habe ich nicht ganz verstanden. Wo muss dass denn hin? Bzw. was
>> bewirkt das?
>
> weniger schreiben, weniger Fehler

So viel macht das hier aber nicht wirklich aus.

> #define ARRAY_SIZE(ARRAY) (sizeof(ARRAY)/sizeof(ARRAY[0]))
>
> for(uint8_t x=0; x<ARRAY_SIZE(cards); ++x)

Es ist gefährlich, das einem Einsteiger so zu empfehlen. Das nächste, 
was der nämlich macht, ist, das in eine Funktion auslagern und sich dann 
wundern, warum es plötzlich nicht mehr funktioniert.

von cppbert (Gast)


Lesenswert?

>> Frank schrieb:
>>> Das habe ich nicht ganz verstanden. Wo muss dass denn hin? Bzw. was
>>> bewirkt das?
>>
>> weniger schreiben, weniger Fehler
>
> So viel macht das hier aber nicht wirklich aus.

aber Pointer sollte er schon kennen, oder?


>> #define ARRAY_SIZE(ARRAY) (sizeof(ARRAY)/sizeof(ARRAY[0]))
>>
>> for(uint8_t x=0; x<ARRAY_SIZE(cards); ++x)
>
> Es ist gefährlich, das einem Einsteiger so zu empfehlen. Das nächste,
> was der nämlich macht, ist, das in eine Funktion auslagern und sich dann
> wundern, warum es plötzlich nicht mehr funktioniert.

wenn es nicht funktioniert ist es doch nicht gefährlich, oder?

ich wollte einfach nur ein paar Grundlagen aufzeigen, mehr nicht

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.