Forum: Compiler & IDEs String Array "indexieren" wie geht das?


von Spannungsteiler (Gast)


Lesenswert?

Hallo Kommunity!

Ich bin dabei C (die Arduino-C) zu lernen, und mit meiner neuen Aufgabe
komme ich nicht weiter. Natürlich habe ich Google schon bemüht, eine 
Lösung zu finden, komme aber einfach nicht weiter.

Ich möchte mit Arduino-UNO über serielle Schnittstelle aus einem
Gerät verschiedene Statuswerte auslesen und danach diesem Gerät
Steuerbefehle schicken. Die Kommunikation funktioniert gut, wenn ich
die Werte und Befehle einzeln lese und schreibe.
Das Ganze schildere ich euch, um zu zeigen was ich in der Praxis 
vorhabe.

Nun zu meiner eigentlicher Frage;
Wie schreibe ich im Arduino-C einen Array, das aus zB. 5 Strings besteht
und durch Indexierung benannt wird ?

Mit Zahlen funktioniert es so:
1
int i;
2
int Wertspeicher[5] = { 1, 3, 5, 7, 9 };
3
int Merker = 0;
4
void setup() {
5
  Serial.begin(9600);
6
  Serial.println("Programm startet...");
7
  delay(1000);
8
}
9
void loop() {
10
if(Merker==0) {                    // Bildschirmausgabe nur einmal
11
  for(i=0; i<6; i++) {
12
    Serial.print("Wert Index: ");
13
    Serial.print(i);
14
    Serial.print(" Wertspeicher: ");
15
    Serial.println(Wertspeicher[i]);
16
  }
17
 }
18
 Merker=1;
19
}

Ich möchte das Gleiche wie oben, nur diesmal statt Zahlen Worte
nehmen (wie im Beispiel unten;)
1
int i;
2
String Worte[5][10] = {"Uhr","Bot","Traktor","Haus","Zange" };
3
int Merker = 0;
4
void setup() {
5
  Serial.begin(9600);
6
  Serial.println("Programm startet...");
7
  delay(1000);
8
}
9
void loop() {
10
if(Merker==0) {         // Bildschirmausgabe nur einmal
11
    for(i=0; i<6; i++) {
12
    Serial.print("Wert Index: ");
13
    Serial.print(i);
14
    Serial.print(" Wertspeicher: ");
15
    Serial.println(Worte[i]);  <---- wie ist es RICHTIG??????
16
  }
17
 }
18
 Merker=1;
19
}
Ich habe mein Problem in 2 kleine Beispiele gehüllt, um euch
das Ganze einfach zu schildern!
Danke für die Hilfe!

von Peter II (Gast)


Lesenswert?

Spannungsteiler schrieb:
> String Worte[5][10] = {"Uhr","Bot","Traktor","Haus","Zange" };

ich kenne jetzt Arduino nicht, aber du willst bestimmt nicht 50 Strings 
haben.
1
String Worte[5] = {"Uhr","Bot","Traktor","Haus","Zange" };

das ganze ist ja mehr C++, bei C müsste man

1
char* Worte[5] = {"Uhr","Bot","Traktor","Haus","Zange" };

oder
1
char Worte[5][10] = {"Uhr","Bot","Traktor","Haus","Zange" };

schreiben.

von Jan L. (ranzcopter)


Lesenswert?

const char *Worte[] = {"Uhr","Bot","Traktor","Haus","Zange" };

von Maro (Gast)


Lesenswert?

Hallo,

in deine for-Schleife die dein Array durchgeht muss noch eine 
for-Schleife eingebaut werden, welche die einzelnen chars durchgeht.

for(int i = 0; i < 6; i++ ){
 for(int j = 0; j < strlen(Worte[i]); j++ ){
   Serial.print(Worte[i][j]);
 }
}

So wird in der inneren Schleife jeder Index in der zweiten Dimension des 
Arrays durchgegangen (Buchstabe für Buchstabe). Danach wird in der 
äußeren Schleife jeder Index der ersten Dimension des Arrays 
durchgegangen (Wort für Wort).


srtlen musst du durch eine Funktion ersetzen, die dir die Länge eines 
Strings gibt. Bin mir nicht sicher ob strlen in der Arduino IDE geht.

von Peter II (Gast)


Lesenswert?

Maro schrieb:
> in deine for-Schleife die dein Array durchgeht muss noch eine
> for-Schleife eingebaut werden, welche die einzelnen chars durchgeht.

nein muss nicht,

Serial.print

nimmt ja String entgehen, damit muss man nicht alle Zeichen von Hand 
übergeben.

von Maro (Gast)


Lesenswert?

Na umso besser ^^

von Spannungsteiler (Gast)


Lesenswert?

Vielen Dank für euere Hilfsbereitschaft!!!!

Peter II schrieb:
> ich kenne jetzt Arduino nicht, aber du willst bestimmt nicht 50 Strings
> haben.

:-) nein, aber 45 Strings, wo der Kürzeste aus 5 char besteht und
der Längste aus 9 char. Deshalb möchte ich nicht so viele verschiedene 
Strings mit unterschiedlichen Namen benennen, sondern "Indexieren".

Bei: String Worte[5][10] =....
wollte ich 5 Strings nehmen, wo für jeden 10char reserviert werden.

Jan L. schrieb:
> const char *Worte[] = {"Uhr","Bot","Traktor","Haus","Zange" };

bringt mir die Fehlermeldung;
>> expected unqualified-id before `char´ <<

von Spannungsteiler (Gast)


Lesenswert?

Peter II schrieb:
> nimmt ja String entgehen, damit muss man nicht alle Zeichen von Hand
> übergeben.

Ja das stimmt, aber wie mache ich es wenn ich String[i]
(42xMal nacheinander)am Bildschirm ausgeben möchte?

Deshalb wollte ich ein [i] INDEX verwenden......
(siehe ursprüngliche Frage).

von Spannungsteiler (Gast)


Lesenswert?

Uppssss, so funktioniert es jetzt;
1
int i;
2
String Worte[5] = {"Uhr","Bot","Traktor","Haus","Zange" };
3
int Merker = 0;
4
void setup() {
5
  Serial.begin(9600);
6
  Serial.println("Programm startet...");
7
  delay(1000);
8
}
9
void loop() {
10
if(Merker==0) {         // Bildschirmausgabe nur einmal
11
    for(i=0; i<6; i++) {
12
    Serial.print(" Index: ");
13
    Serial.print(i);
14
    Serial.print(" Wort: ");
15
    Serial.println(Worte[i]);  
16
  }
17
 }
18
 Merker=1;
19
}

Dabei verstehe ich nicht ganz, warum ich die Platzhalter [10] für
die Stringlänge nicht angeben muss???
also nicht so;
String Worte[5][10] = {"Uhr","Bot","Traktor","Haus","Zange" };
sonndern so:
String Worte[5] = {"Uhr","Bot","Traktor","Haus","Zange" };

von Erwin D. (Gast)


Lesenswert?

Spannungsteiler schrieb:
> Dabei verstehe ich nicht ganz, warum ich die Platzhalter [10] für
> die Stringlänge nicht angeben muss???
> also nicht so;
> String Worte[5][10] = {"Uhr","Bot","Traktor","Haus","Zange" };
> sonndern so:
> String Worte[5] = {"Uhr","Bot","Traktor","Haus","Zange" };

Weil du sonst 5 mal 10 Strings reservierst.
Wenn du es so schreibst:
1
char worte[5][10] = {"Uhr","Bot","Traktor","Haus","Zange" };
dann reservierst du 5 mal 10 Chars. Hier mußt du aber eben jedes Zeichen 
einzeln ausgeben (mit der angesprochenen Extra-Schleife).
Oder du schreibst
1
char worte[5][10] = {"Uhr\0","Bot\0","Traktor\0","Haus\0","Zange\0" };.....
dann wird auch das String-Ende erkannt.
Im Endeffekt ist es aber am übersichtlichsten und am einfachsten, wenn 
du die string-Schreibweise nimmst.
1
String Worte[5] = {"Uhr","Bot","Traktor","Haus","Zange" };

von Spannungsteiler (Gast)


Lesenswert?

Maro schrieb:
> Bin mir nicht sicher ob strlen in der Arduino IDE geht

die funktionierende Zeile lautet;

     Serial.println(Worte[i]);

und so komme ich auf Stringlänge:

    Serial.println(Worte[i].length());

Super, DANKE für euere Unterstützung!

Es sieht so aus,dass Arduino Compiler die Stringlänge (n) selber im 
Speicher reserviert, deshalb muss ich nicht so deklarieren;

String Worte[i][n]="...........

Ich sehe es mitunter, dass die Anzahl (i) vom Strings auch nicht angeben 
muss!
es reicht einfach  String Worte[]=".......
zu schreiben.

Erwin D. schrieb:
> Im Endeffekt ist es aber am übersichtlichsten und am einfachsten, wenn
> du die string-Schreibweise nimmst.
String Worte[5] = > {"Uhr","Bot","Traktor","Haus","Zange" };

DANKE!!!!

von Jan L. (ranzcopter)


Lesenswert?

Spannungsteiler schrieb:
> Jan L. schrieb:
>> const char *Worte[] = {"Uhr","Bot","Traktor","Haus","Zange" };
>
> bringt mir die Fehlermeldung;
>>> expected unqualified-id before `char´ <<

bei mir compiliert das einwandfrei:
1
void loop() {
2
  // put your main code here, to run repeatedly:
3
const char *Worte[5] = {"Uhr","Bot","Traktor","Haus","Zange" };
4
int i;
5
for(i=0; i<6; i++) {
6
    Serial.print(" Index: ");
7
    Serial.print(i);
8
    Serial.print(" Wort: ");
9
    Serial.println(Worte[i]);  
10
  }
11
}

und bringt die Ausgabe:
1
Der Sketch verwendet 1.616 Bytes (5%) des Programmspeicherplatzes. Das Maximum sind 32.256 Bytes.
2
Globale Variablen verwenden 240 Bytes (11%) des dynamischen Speichers, 1.808 Bytes für lokale Variablen verbleiben. Das Maximum sind 2.048 Bytes.

Das gleiche mit "String" tut natürlich auch, benötigt aber fast den 
doppelten Speicher...

von Peter II (Gast)


Lesenswert?

Spannungsteiler schrieb:
> Es sieht so aus,dass Arduino Compiler die Stringlänge (n) selber im
> Speicher reserviert, deshalb muss ich nicht so deklarieren;

das ist ganz normales C++ mit einer String klasse. Es gibt keinen 
"Arduino Compiler" das ist ein normaler gcc

von Spannungsteiler (Gast)


Lesenswert?

Jan L. schrieb:
> bei mir compiliert das einwandfrei:

Hallo Jan! Das ist mir total peinlich! Ich kann es nichtmal
Anfängerfehler nennen, sondern >dumm< ....von mir !

Ich habe den Stern falsch gesetzt, so! ;
const *char Worte[5] = {"Uhr","Bot","Traktor","Haus","Zange" };

dann bekam ich die Fehlermeldung!

Super, dass Du deinen Vorschlag nocheinmal postest!
Ich habe mit pointers noch überhaupt nicht gearbeitet, bin beim
elrernen von Arduino-C++, deshalb ist mir die Schreibweise mit "*"
noch ganz unbekannt.

Das Lernen geht weiter, und ich bin froh, hier im Forum Unterstützung
zu bekommen!!!! DANKE!

von guest (Gast)


Lesenswert?

1
  ...
2
  for(i=0; i<6; i++) {
3
  ...
Wenn man nur 5 Strings hat sollte man nicht versuchen 6 auszugeben!

Erwin D. schrieb:
> Wenn du es so schreibst:
> char worte[5][10] = {"Uhr","Bot","Traktor","Haus","Zange" };
> dann reservierst du 5 mal 10 Chars. Hier mußt du aber eben jedes Zeichen
> einzeln ausgeben (mit der angesprochenen Extra-Schleife).
> Oder du schreibst
> char worte[5][10] = {"Uhr\0","Bot\0","Traktor\0","Haus\0","Zange\0" };.....
> dann wird auch das String-Ende erkannt.

Das ist Quatsch. Ein Stringliteral enthält schon per Definition die 
abschließende 0, die muß man nicht extra angeben. Notwendig wäre das nur 
wenn man alle Zeichen einzeln angibt:
1
char worte[5][10] = {
2
  { 'U', 'h', 'r', '\0' },
3
  { 'B', 'o', 't', '\0' },
4
  { 'T', 'r', 'a', 'k', 't', 'o', 'r', '\0' },
5
  { 'H', 'a', 'u', 's', '\0' },
6
  { 'Z', 'a', 'n', 'g', 'e', '\0' },
7
};

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.