Forum: Compiler & IDEs Statische 2D Char Arrays mit verschiedenen Größen


von Werner D. (werner_d350)


Lesenswert?

Hi, kann man statische 2D Char Arrays mit verschiedenen Größen 
definieren ?
Normalerweise sind die Größen immer gleich, also z.B. char a[5][10].
Also 5 Char Arrays mit jeweils 10 Chars.

Kann ich jetzt die ersten 2 Char Arrays mit 100 Bytes deklarieren ?
So daß
sizeof(a[0]) = 100
sizeof(a[1]) = 100
sizeof(a[2]) = 10
sizeof(a[3]) = 10
sizeof(a[4]) = 10

Ich möchte keine dyn. Arrays auf dem Heap haben.

Viele Grüße
Werner

von Michael B. (laberkopp)


Lesenswert?

Werner D. schrieb:
> Kann ich jetzt die ersten 2 Char Arrays mit 100 Bytes deklarieren ?
1
char a1[100],a2[100],a3[10],a4[10],a5[10];
2
char (*a)[5]={a1,a2,a3,a4,a5};
Zugriff mit
1
a[x][y]
und nicht
1
a[x,y]

: Bearbeitet durch User
von Werner D. (werner_d350)


Lesenswert?

Michael B. schrieb:
> char a1[100],a2[100],a3[10],a4[10],a5[10];
> char (*a)[5]={a1,a2,a3,a4,a5};

Funktioniert das auch unter c++ ?
Ich bekomme da ein Compiler Fehler error: scalar object 'a' requires one 
element in initializer

von Mikro 7. (mikro77)


Lesenswert?

Michael B. schrieb:
> char (*a)[5]= ...
Das wäre ein pointer auf ein array mit 5 chars.

Es sollte wohl heißen:
1
char *a[5]={a1,a2,a3,a4,a5};

Der sizeof operator funktioniert damit allerdings nicht so wie du dir 
das wünschst:

Werner D. schrieb:
> Kann ich jetzt die ersten 2 Char Arrays mit 100 Bytes deklarieren ?
> So daß
> sizeof(a[0]) = 100
> sizeof(a[1]) = 100
> sizeof(a[2]) = 10
> sizeof(a[3]) = 10
> sizeof(a[4]) = 10

von Werner D. (werner_d350)


Lesenswert?

Mikro 7. schrieb:
> Es sollte wohl heißen:char *a[5]={a1,a2,a3,a4,a5};

Da waren sie wieder, die Probleme mit den Pointern :))

Danke, compilieren hat schon mal funktioniert. Muß ich mir nur überlegen 
was ich anstelle von sizeof mache.

von Harald K. (kirnbichler)


Lesenswert?

Werner D. schrieb:
> Muß ich mir nur überlegen
> was ich anstelle von sizeof mache.

Na, was willst Du erreichen?

Willst Du zur Laufzeit herausfinden, wie groß Deine Arrays sind, und das 
nur aus a[] heraus?

Das könntest Du mit einem zusätzlichen Array erreichen:
1
char a1[100],a2[100],a3[10],a4[10],a5[10];
2
char *a[5]={a1,a2,a3,a4,a5};
3
char s[5]={sizeof(a1),sizeof(a2),sizeof(a3),sizeof(a4),sizeof(a5)};

(Übrigens kann bei der Arraydefinition für a[] und s[] die 5 weggelassen 
werden, der Compiler kann selbst zählen und bestimmt die Anzahl der 
Arrayelemente aus der Anzahl der Initialisierer)

Beitrag #7467950 wurde vom Autor gelöscht.
von Wilhelm M. (wimalopaan)


Lesenswert?

Du fragst nach C++? Dann nimm std::array<>. Weil nun unterschiedlich 
große Arrays jeweils unterschiedliche DT haben, kann man die Arrays oder 
Zeiger darauf nicht in einem anderen weiteren homogenen Container 
speichern. Da kommt std::variant<> ins Spiel. Zwar könnte man auf die 
Zeiger verzichten und die Array-Typen zu den Parametern des 
std::variant<> machen, was aber ungünstig ist, weil dann der 
Speicherbedarf steigt (std::variant<> ist eine type-safe-union). Also 
nimmt man Zeiger.
1
#include <cstdint>
2
#include <array>
3
#include <variant>
4
5
using a1_t = std::array<char, 100>;
6
using a2_t = std::array<char, 10>;
7
using v_t = std::variant<a1_t*, a2_t*>;
8
9
a1_t a1;
10
a1_t a2;
11
a2_t a3;
12
a2_t a4;
13
a2_t a5;
14
15
int main() {
16
    std::array<v_t, 5> aa{&a1, &a2, &a3, &a4, &a5};
17
18
    uint16_t l = 0;
19
20
    for(auto& e: aa) {
21
        std::visit([&](auto&& a){
22
            l += a->size();
23
        }, e);
24
    }
25
    return l;
26
}

: Bearbeitet durch User
von Wilhelm M. (wimalopaan)


Lesenswert?

Und wenn Du die Große der Arrays nicht als Compile-Zeit-Konstante 
benötigst, kannst Du auch gut ein std::span<> nehmen:
1
#include <cstdint>
2
#include <array>
3
#include <variant>
4
#include <span>
5
6
using a1_t = std::array<char, 100>;
7
using a2_t = std::array<char, 10>;
8
9
a1_t a1;
10
a1_t a2;
11
a2_t a3;
12
a2_t a4;
13
a2_t a5;
14
15
int main() {
16
    uint16_t l{};
17
18
    std::array<std::span<char>, 5> bb{a1, a2, a3, a4, a5};
19
    for(const auto& s: bb) {
20
        l += s.size();
21
    }
22
23
    return l;
24
}

von Daniel A. (daniel-a)


Lesenswert?

In C ist dies nicht möglich. Aber normalerweise braucht man sowas auch 
nicht. Dann packt man hat 2 Arrays in ein Struct.
1
struct {
2
  char a[5][10];
3
  char b[2][100];
4
} x;

Oder man macht sich eine Funktion (ungetestet):
1
#define SIZES X(5,10) X(2,100)
2
#define X(a,b) a*b+
3
typedef char specialarray_t[SIZES 0]
4
#undef X
5
size_t get_entry(char** ret, specialarray_t array, size_t index){
6
#define X(a,b) \
7
  if(index < a){ \
8
    *ret = array + index * b; \
9
    return b; \
10
  } \
11
  array += a*b; \
12
  index -= a;
13
  SIZES
14
#undef X
15
  *ret = 0;
16
  return 0;
17
}
18
#undef SIZES

Oder man speichert sich die Grösse auch noch irgendwo in der 
Datenstruktur ab. Kommt halt ganz drauf an, was man damit machen will.

: Bearbeitet durch User
von Rolf M. (rmagnus)


Lesenswert?

Harald K. schrieb:
> Willst Du zur Laufzeit herausfinden, wie groß Deine Arrays sind, und das
> nur aus a[] heraus?
>
> Das könntest Du mit einem zusätzlichen Array erreichen:

Da man Arrays aus char eh nur für Text verwenden sollte, kann man dann 
auch gleich die in C übliche Nullterminierung verwenden und hat dann 
auch die Länge und kann die ganzen Stringfunktionen von C verwenden.

von Werner D. (werner_d350)


Lesenswert?

Vielen Dank für die ganzen Antworten.
Ich habe es jetzt so gemacht wie Harald/Mikro 7/Michael es beschrieben 
hat. War am einfachsten in die bestehende Programmierung einzubinden ( 
Die war etwas umständlich)
Ich brauchte eine Funktion ähnlich der split-Funktion in JS und dazu 
brauche ich ein Array von char-Arrays (Strings).

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.