Forum: Mikrocontroller und Digitale Elektronik char* pointer(Zeiger) einem String zuweisen, merkwürdiges Verhalten


von JoJoBa (Gast)


Lesenswert?

Hallo!!!
Bastele gerade an einem Prog. für eine Jalousiene-Steuerung mit
einem Arduino-Uno, Relaiskarte und 2x 8x8 MAX7219 Led-Matrix.
Auf den 2 Led-Matrix laufen die Kommunikationsinfos und andere
Werte, die als Laufschrift, Scrolltext ausgegeben werden.

Bei diesem Matrix-Code-Abschnitt stösse ich auf ein merkwürdiges
Verhalten von Zuweisung des Pointers auf ein String.

 Nachdem die while Schleife abgearbeitet ist (wo ich einen einfachen
Scrolltext realisiere), möchte ich nach nächstem Loop vor der Schleife
den Pointer mit if Bedinguhn wieder auf dem Anfang vom String führen,
damit der Scrolltext immer wieder von neuem durchlauft.

Nun, habe ich im Code die Zeilen ausklammert dort wo dies nicht 
funktioniert!
Der untere Code funktioniert so wie ich ihn poste, aber nicht mehr,wenn 
sich

char* s=string;  in den Zeilen 26 oder 48 befindet.

Warum ist es so, was mache ich denn falsch?
( die viele Serial.prints sind nur wegen Fehlersuche drin)


1
// Einzelne Char mit Pointer aus dem String auslesen
2
// Testprogramm 2015 Textscroll
3
// 
4
char string[] = "<ABC321>";
5
int stringlaenge=strlen(string)+1;  // +1 wegen Nullterminierung
6
int counter=0; 
7
char* s=string; // Pointer zeigt auf erste char im string 
8
  
9
  void setup(){
10
  Serial.begin(19200);
11
  Serial.print(" Stringlaenge ");
12
  Serial.println(stringlaenge);//
13
  Serial.println(" Programm startet..... ");
14
  delay(1000); 
15
  
16
}
17
//--------------------------------------------------------
18
void loop() {   
19
  
20
  Serial.println(" ---------------neues Loop ----------- ");
21
  Serial.print(" Loop counter= ");Serial.println(counter); 
22
  Serial.print(" StringLaenge= ");Serial.println(stringlaenge); 
23
  
24
  if(stringlaenge==1) {
25
   Serial.println(" Stringlaenge wird neu ermittelt----------- ");
26
   //char* s=string;//dieser Befehl funktioniert hier nicht!!!! 
27
    stringlaenge=strlen(string)+1;
28
   }
29
  
30
 char* s=string;// ohne diese Zeile gibt es nur 1 Textdurchlauf.
31
                // Sonnst immer wiederholt Textscroll
32
                // HIER FUNKTIONIERT ES
33
  int num=*s ;
34
  Serial.print(" char* s=string ");Serial.print(*s);
35
  Serial.print(" ascii ");Serial.println(num);
36
//if (*s != 0)// solange die Nullterminierung am Ende vom string erreicht wird...
37
 
38
 while (*s != 0) // gleichbedeutend mit = while (*s)
39
  {
40
    Serial.print(" StringLaenge= ");Serial.println(stringlaenge);
41
    Serial.print(" Char Pointer *s: ");Serial.print(*s);// *s ist die jeweilige Buchstabe
42
    Serial.print(" : ");
43
    Serial.print(" Scrolltext string s: ");Serial.println(s);// Der ganze übrige string 
44
    
45
    stringlaenge--;
46
    s++;// Pointer auf nächste Char im String
47
    delay(1000);
48
  }
49
//char* s=string;//hier funktioniert diese Anweisung auch nicht!!!! Warum?????
50
  counter++;// Loop Durchläufe zählen
51
  if(counter>30000) counter=0; 
52
  delay(500);
53
}//----------------------------Loop Ende----------------------------

Vielen Dank für euere Hilfe!
MfG csaba
>>Jeder ist solange gesund, bis er von einem Artzt untersucht worden ist<<

von Klaus (Gast)


Lesenswert?

Seufz. Ich sage sonst nix. Dann kann ich auch niemandem zu nahe treten.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

JoJoBa schrieb:
> Serial.print(*s);

Das in *s stehende Zeichen wird als Adresse eines Strings interpretiert.

Soll das so?  Und warum beachtest du keine Warnungen?

von Markus F. (mfro)


Lesenswert?

JoJoBa schrieb:
> Warum ist es so, was mache ich denn falsch?

Variablen sind nur innerhalb des Blocks bekannt, in dem sie deklariert 
wurden.
Blöcke sind die Bereiche, die zwischen '{' und '}' stehen.

von JoJoBa (Gast)


Lesenswert?

@Gjlayde
Ich bekomme keine Warnungen, der sketch funzt eiwandfrei wenn
char* s=string;
sich im Loop vor der while-Schleife befindet.
Der Scrolltext wird in jedem Loop einmal durchgeführt.

Wenn sich aber
char* s=string;  nach der while-Schleife eingefügt wird
oder davor im if...
dann bekomme ich NUR EINEN TEXTDURCLAUF.
deshalb verstehe ich dieses Verhalten nicht!!!???

@mfro
Du hast Recht, aber das ist hier gegeben!
Alle Wariablen sind global deklariert, vor dem setup!
....oder verstehe ich etwas nicht?


Gruß,csaba

von STK500-Besitzer (Gast)


Lesenswert?

Johann L. schrieb:
> Das in *s stehende Zeichen wird als Adresse eines Strings interpretiert.

Nö. Damit wird der Inhalt einer Speicherstelle zurückgeliefert - also 
ein Buchstabe/Zeichen.

von Bauteiltöter (Gast)


Lesenswert?

STK500-Besitzer schrieb:
> Johann L. schrieb:
>> Das in *s stehende Zeichen wird als Adresse eines Strings interpretiert.
>
> Nö. Damit wird der Inhalt einer Speicherstelle zurückgeliefert - also
> ein Buchstabe/Zeichen.

Genau. und dieser Buchstabe/Zeichen wird dann an eine FUnktion 
übergeben, die die Adresse eines Strings haben will!

von Markus F. (mfro)


Lesenswert?

JoJoBa schrieb:
> Du hast Recht, aber das ist hier gegeben!
> Alle Wariablen sind global deklariert, vor dem setup!
> ....oder verstehe ich etwas nicht?

Ja. Eine Deklaration einer Variable in einem "inneren" Block "überdeckt" 
die gleichnamige Variable aus einem "äußeren" Block. Du hast dann halt 
zwei Variablen gleichen Namens (das ist durchaus erlaubt), kannst aber 
"innen" nur auf die innere zugreifen. Wird der Block verlassen, 
verschwindet die "innere" Variable (und alles, was Du da reingeschrieben 
hast).

1
char *s = string;
Deklariert (und initialisiert) eine (neue) Variable.

: Bearbeitet durch User
von JoJoBa (Gast)


Lesenswert?

Wenn ich den Sketch ins Arduino UNO lade und den Seriellen Monitor
aktiviere, dann kann ich schön beobachten wie die einzelne
Buchstaben in der Reihe nach einzeln ausgegeben werden!

Genau das, was ich auch haben will.
Die while-Schleife tut was es soll und die *s tut auch was es soll!

Nun will ich in jedem Loopdurchlauf diesen Text im string
immer wieder von neuem durchführen.
Dazu muss ich vor der while-Schleife dem Pointer *s sagen,
dass er wiedermal auf die erste char im string zeigen soll.

Die klappt es dann wenn:
char* s=string;   vor dem while vorkommt!
es klappt nicht, wenn
char* s=string;  nach dem wheil eingefügt wird!
(hier wird while nur 1x ausgeführt und dann nicht mehr, so wie wenn
char* s=string; überhaupt nicht da wäre)

Und genau das ist für mich ein Rätsel, da ich später den
Befehl  char* s=string;  in eine if Bedingung packen muss!
Es wird benötigt für das weitere Programm, aber ich muss zuerst
diesen Sachverhalt klären, sonnst komme ich nicht weiter.

Studiere seit 2 wochen alles was ich über Pointer im web finde,
und da ich steckengeblieben bin, bitte ich um euere Hilfe
bei diesem Problem!
Danke vielmals!!!!

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

JoJoBa schrieb:
> sketch

Sketch: ist eine kurze komödiantische Szene, die einer reduzierten 
Handlung folgt und mit einer prägnanten Schlusspointe abschließt.

Okay, du hast uns erwischt!

von STK500-Besitzer (Gast)


Lesenswert?

1
char* s=string;

damit erzeugst du die pointer-Variable s und weist ihr "gleichzeitig" 
den Wert von string zu (etwas verkürzt geschrieben).

Wenn du diese beiden Befehle trennst, klappt es auch:
1
char* s;
2
s=string;

von STK500-Besitzer (Gast)


Lesenswert?

Johann L. schrieb:
> Sketch: ist eine kurze komödiantische Szene, die einer reduzierten
> Handlung folgt und mit einer prägnanten Schlusspointe abschließt.

oder eine Skizze...

von Kaffee oder Tee (Gast)


Lesenswert?

JoJoBa schrieb:
> Studiere seit 2 wochen alles was ich über Pointer im web finde,
> und da ich steckengeblieben bin, bitte ich um euere Hilfe
> bei diesem Problem!

Wie wärs wenn du erst mal ordentlich C++ lernen würdest mit einem Buch. 
Damit sparst du dir eine Menge Frust.

von Oliver S. (oliverso)


Lesenswert?

JoJoBa schrieb:
> Studiere seit 2 wochen alles was ich über Pointer im web finde,

Studier ruhig weiter, das wird dir später sicher nützlich sein. Dein 
aktuelles Problem löst du so aber nicht, das hat nämlich mit Pointern 
wenig zu tun.

Oliver

von OldMan (Gast)


Lesenswert?

JoJoBa schrieb:
> Der Scrolltext wird in jedem Loop einmal durchgeführt.
Soweit ich informiert bin, ist loop() mit dem main() eines Standard C 
Programmes identisch. D.h., Deine neue Zuweisung an *s bringt nichts, da
loop() nach der while-Schleife beendet wird. Gemeint ist, dass loop() 
terminiert und Dein AVR nichts mehr macht.
Nach einem Reset wird dann loop() wieder einmal ausgeführt.
Du solltest um die derzeitige while-Schleife noch eine zweite legen.
Etwa so:
1
while (1){ // Dauerschleife....bis zum Reset oder neuem Programm flashen
2
3
while (*s != 0) // gleichbedeutend mit = while (*s)
4
  {
5
    Serial.print(" StringLaenge= ");Serial.println(stringlaenge);
6
    Serial.print(" Char Pointer *s: ");Serial.print(*s);// *s ist die jeweilige Buchstabe
7
    Serial.print(" : ");
8
    Serial.print(" Scrolltext string s: ");Serial.println(s);// Der ganze übrige string 
9
    
10
    stringlaenge--;
11
    s++;// Pointer auf nächste Char im String
12
    delay(1000);
13
   }
14
} // while(1) 
15
  char* s=string;
16
  stringlaenge = strlen(s); /* +1 brauchst Du nicht! */
17
  counter++;// Loop Durchläufe zählen
18
  if(counter>30000) counter=0; 
19
  delay(500);
20
}
Verstanden?

von OldMan (Gast)


Lesenswert?

Da war ein Fehler drin..
1
while (1){ // Dauerschleife....bis zum Reset oder neuem Programm flashen
2
3
while (*s != 0) // gleichbedeutend mit = while (*s)
4
  {
5
    Serial.print(" StringLaenge= ");Serial.println(stringlaenge);
6
    Serial.print(" Char Pointer *s: ");Serial.print(*s);// *s ist die jeweilige Buchstabe
7
    Serial.print(" : ");
8
    Serial.print(" Scrolltext string s: ");Serial.println(s);// Der ganze übrige string 
9
    
10
    stringlaenge--;
11
    s++;// Pointer auf nächste Char im String
12
    delay(1000);
13
   }
14
/****************} // while(1)  <-- Das war falsch von mir ;-(
15
  char* s=string;
16
  stringlaenge = strlen(s); /* +1 brauchst Du nicht! */
17
  counter++;// Loop Durchläufe zählen
18
  if(counter>30000) counter=0; 
19
  delay(500);
20
}// while(1) hier gehört es hin...

von JoJoBa (Gast)


Lesenswert?

Ich sehe, ich muss noch etwas Hintergrundinfo zu meinem Hilferuf
zufügen :) ;
Der Programmschnippsel soll später ohne DELAY laufen,damit die
anderen Aufgaben auch "gleichzeitig" bearbeitet werden.
Deshalb benütze ich in Weiterem dann millis() timing statt delay
und deshalb kann ich kein while mer verwenden sondern das if.....

Zurück zu meinem Problem;
Der if wird benötigt um beim erreichen der \0 Terminierung im
String wieder den Pointer *s auf den Anfang vom String zu setzen...

Dies wollte ich mit gepostetem Code zeigen (siehe Beitragsanfang)
hier;   //if (*s != 0)//
(es ist noch ausgeklammert weil es nicht funktioniert hat)

Darf ich die Hilfestellung also auch so formulieren;
Wie sollte der Codebeispiel aussehen, damit mein Vorhaben ohne delay,
also ohne while aber mit if Bedingung alle x sekunden den
Beispieltext Buchstabenweise immerwieder ausgibt.

Nun ich bin über 50 und C Programmierung lerne ich im Eigenstudium
seit einem Jahr, weil es mir mega Spass macht und will euere Zeit
nicht damit rauben, mir fertige Lösungen zu liefern.
Stolpere ich aber gerade über ein Steinchen, wo ich selber nicht
weiter weiß :-(

@STK500-Besitzer
habe gerade Dein Vorschlag probiert, es klappt aber leider noch nicht...

@ OldMan
Danke Dir für das Beispiel.
void loop() {
....tu was
}
wird ziklisch immer wieder ausgeführt, ist ja eine Schleife.
Bitte beachte; Der Code lauft eiwandfrei, der Text im String
wird Buchstabenweise auf dem Serial Monitor ausgegeben!

dieses Verhalten ändert sich auf-> Text wird nur 1Mal rotiert

wenn sich    char* s=string;
in der Zeile im void loop()  hinter der while-Schleife plaziert wird!
(@STK500-Besitzer sein Vorschlag mit
char* s;
s=string;   habe auch probiert)

Hätte ich probleme mit dem     char* s=string;  dann
dürfte das Programm nicht laufen.
Es tut es aber, wenn sich   char* s=string;
in eine Zeile vor dem while eingefügt wird !?

von JoJoBa (Gast)


Lesenswert?

Habe den Code etwas vereinfacht und möchte ihn nochmal posten
wenn der Text zyklisch "rotiert" wird hier;
1
// Einzelne Char mit Pointer aus dem String auslesen
2
// Testprogramm 2015 Textscroll
3
// 
4
char string[] = "<ABC321>";
5
int stringlaenge=strlen(string)+1;  // +1 wegen Nullterminierung
6
char* s=string; // Pointer zeigt auf erste char im string 
7
  
8
  void setup(){
9
  Serial.begin(19200);
10
  Serial.print(" Stringlaenge ");  Serial.println(stringlaenge);//
11
  Serial.println(" Programm stertet..... ");
12
  delay(1000); 
13
}
14
//--------------------------------------------------------
15
void loop() {   
16
  Serial.println("neues Loop ");
17
  if(stringlaenge==1) {
18
   Serial.println(" Stringlaenge wird neu ermittelt----------- ");
19
   //char* s=string;//dieser Befehl funktioniert hier nicht!!!! 
20
    stringlaenge=strlen(string)+1;
21
   }
22
  
23
 char* s=string;// ohne diese Zeile gibt es nur 1 Textdurchlauf.
24
                // Sonnst immer wiederholt Textscroll
25
                // HIER FUNKTIONIERT ES
26
  
27
 while (*s != 0) // gleichbedeutend mit = while (*s)
28
  {
29
    Serial.print(" StringLaenge= ");Serial.println(stringlaenge);
30
    Serial.print(" Char Pointer *s: ");Serial.print(*s);// *s ist die jeweilige Buchstabe
31
    Serial.print(" : ");
32
    Serial.print(" Scrolltext string s: ");Serial.println(s);// Der ganze übrige string 
33
    stringlaenge--;
34
    s++;// Pointer auf nächste Char im String
35
    delay(1000);
36
  }
37
//char* s=string;//hier funktioniert diese Anweisung auch nicht!!!! Warum?????
38
   delay(500);
39
}//----------------------------Loop Ende----------------------------

---und hier ist die Variante wo der Text nur 1Mal "rotiert" wird
und danach nicht mehr:
1
// Einzelne Char mit Pointer aus dem String auslesen
2
// Testprogramm 2015 Textscroll
3
// 
4
char string[] = "<ABC321>";
5
int stringlaenge=strlen(string)+1;  // +1 wegen Nullterminierung
6
char* s=string; // Pointer zeigt auf erste char im string 
7
  
8
  void setup(){
9
  Serial.begin(19200);
10
  Serial.print(" Stringlaenge ");  Serial.println(stringlaenge);//
11
  Serial.println(" Programm stertet..... ");
12
  delay(1000); 
13
}
14
//--------------------------------------------------------
15
void loop() {   
16
  Serial.println("neues Loop ");
17
  if(stringlaenge==1) {
18
   Serial.println(" Stringlaenge wird neu ermittelt----------- ");
19
   //char* s=string;//dieser Befehl funktioniert hier nicht!!!! 
20
    stringlaenge=strlen(string)+1;
21
   }
22
  
23
 //char* s=string;// ohne diese Zeile gibt es nur 1 Textdurchlauf.
24
                // Sonnst immer wiederholt Textscroll
25
                // HIER FUNKTIONIERT ES
26
  
27
 while (*s != 0) // gleichbedeutend mit = while (*s)
28
  {
29
    Serial.print(" StringLaenge= ");Serial.println(stringlaenge);
30
    Serial.print(" Char Pointer *s: ");Serial.print(*s);// *s ist die jeweilige Buchstabe
31
    Serial.print(" : ");
32
    Serial.print(" Scrolltext string s: ");Serial.println(s);// Der ganze übrige string 
33
    stringlaenge--;
34
    s++;// Pointer auf nächste Char im String
35
    delay(1000);
36
  }
37
char* s=string;//hier funktioniert diese Anweisung auch nicht!!!! Warum?????
38
   delay(500);
39
}//----------------------------Loop Ende----------------------------

.....Danke für euere Aufmerksamkeit!
csaba

von Klaus (Gast)


Lesenswert?

Ja, ja. Arduino schafft Probleme, die wir ohne es nicht hätten. 
Scheussliches Zeug!

Die Funktion "loop" wird endlos immer wieder aufgerufen.
Siehe: 
http://forum.arduino.cc/index.php?PHPSESSID=4298fmuetk14gba8sbbfskkk31&topic=45911.msg333093#msg333093

Das ist kein C-Schlüsselwort, wie etwa "while" oder "for".

Ohne Gewähr! Offen gesagt, will ich es so genau denn auch wieder nicht 
wissen.


Dann ist das ein C-Problem. An dieser Stelle kann man nur wieder mal von 
Arduino abraten. Das ist die P... im A...

Wenn Du wiederholt oder auch an verschiedenen Stellen im Code der loop 
Funktion die "Deklaration" mit "Initialisierung" hinsetzt, dann 
überdeckt diese Deklaration alle in den jeweils äusseren "Blöcken" 
deklarierten gleichnamigen Variablen.

D.h. Wenn Du ein zweites Mal in die Funktion loop eintrittst, dann sind 
alle Deine Wertveränderungen von Variablen, die innerhalb von loop 
erfolgen, verloren.

Das Programm verfolgt insofern auch den korrekten Ansatz, char s 
zunächst ausserhalb jeder Funktion zu deklarieren.
Mit den nachfolgenden Deklarationen aber, überdeckst Du, wie schon (und 
nicht nur von mir) erwähnt die äusserste Deklaration. Das sind ganz 
andere Variablen.

Also: Gleich C lernen und den ganzen Arduino-Plumpaquatsch jemandem 
schenken, dem Du zwar das Schlechteste wünschst, aber wozu Dir nichts 
Besseres einfällt.

von Klaus (Gast)


Lesenswert?

Das muss ich in dem Zusammenhang präziser sagen:

D.h. Wenn Du ein zweites Mal in die Funktion loop eintrittst, dann sind
alle Deine Wertveränderungen von Variablen, die innerhalb von loop
erfolgen, und die innerhalb der Funktion deklariert sind verloren.

von JoJoBa (Gast)


Lesenswert?

@KLAUS
>Das Programm verfolgt insofern auch den korrekten Ansatz, char s
zunächst ausserhalb jeder Funktion zu deklarieren.
Mit den nachfolgenden Deklarationen aber, überdeckst Du, wie schon (und
nicht nur von mir) erwähnt die äusserste Deklaration. Das sind ganz
andere Variablen.<

OK, ich werde es reinziehen....
Wie würde es "richtig" aussehen, bzw. wie soll ich dann
folgendes realisieren;
1
 if(stringlaenge==1) {
2
    Serial.println(" Stringlaenge wird neu ermittelt------------------------ ");
3
    char* s=string; 
4
    stringlaenge=strlen(string)+1;
5
   }
...ich möchte damit dem Programm folgendes sagen;
  wenn die stringlänge erreicht ist,
  setze den *s Pointer auf dem 1.char im string!
  ...damit der nächste while das gleiche macht wie bisher beim ersten
  durchlauf.

und das klappt so nicht!?   wie dann?

Gruß!

von JoJoBa (Gast)


Lesenswert?

Liebe programmierer Freunde!
ich wage Jetzt einen neuen Ansatz um mir Hilfe zu holen.

Den bisherigen Code habe ich eingefügt um zu zeigen in welchen 
Schwierigkeiten ich mich bei einem neuem Programm befinde.
Leider bin ich auf diese Weise nicht weitergekommen, deshalb poste ich
hier die Version, die bei mir in Einsatz kommen soll.

Der Code lauft auf einem Arduino-Uno und ich nutze die IDE 1.5.8 
bzw.1.6.4
Im Code ist ein String mit einem Text definiert.Der Text wird
Buchstabenweise nacheinander auf dem IDE serial Monitor -alle 2 sekunden
die nächste Buchstabe, ausgegeben.
Soweit-sogut, dies funktioniert am Anfang
(1x Text Buchstabenweise anzeigen)tadellos.

Nacdem aber der *s Pointer die \0 Terminierung erreicht hat,
zeigt er mir nicht mehr wieder auf die 1.Buchstabe im Text.
obwohl ich versuche dies neu zuzuweisen mit :
char* s=string;

dieser Ausschnitt hat dann keine wirkung:
1
if(stringlaenge==1) {
2
    Serial.println(" Stringlaenge wird neu ermittelt------------------------ ");
3
    char* s=string;  // Zeige auf den ersten char im string
4
    stringlaenge=strlen(string)+1;
5
   }
Was mache ich hier falsch, bzw wie schreibe ich es richtig?

Über eine richtige Lösung wäre ich sehr erfreut!
Weiter Oben in den Hilfeansätzen von Teilnehmer wurden auf verschiedene
Dinge hingewiesen, die alle konnte ich aber noch nicht erfolgreich
verwenden.

hier ist mein Code:
1
// Einzelne Char mit Pointer aus dem String auslesen
2
// Testprogramm 2015 ohne DELAY
3
// 
4
unsigned long zeitstempel; // Variable um den aktuellen Zeitwert zu speichern
5
unsigned long displaychar;
6
int zeitfenster = 2000; // 2 sec
7
8
char string[] = "<ABC321>";
9
int stringlaenge=strlen(string)+1;  // +1 wegen Nullterminierung
10
char* s=string; // Pointer zeigt auf erste char im string
11
  
12
  void setup(){
13
  Serial.begin(19200);
14
  Serial.print(" Stringlaenge ");
15
  Serial.println(stringlaenge);//
16
  Serial.println(" Programm stertet..... ");
17
  delay(1000); 
18
  
19
}
20
//--------------------------------------------------------
21
void loop() {   
22
  zeitstempel=millis();
23
  Serial.println(" ---------------neues Loop ----------- ");
24
  Serial.print(" StringLaenge= ");Serial.println(stringlaenge); 
25
 if(stringlaenge==1) {
26
    Serial.println(" Stringlaenge wird neu ermittelt------------------------ ");
27
    char* s=string;  // Zeige auf den ersten char im string
28
    stringlaenge=strlen(string)+1;
29
   }
30
     
31
 if ((zeitstempel - displaychar) >= zeitfenster) 
32
 { 
33
   if (*s != 0)// solange die Nullterminierung am Ende vom string erreicht wird...
34
   {
35
    Serial.print(" StringLaenge= ");Serial.println(stringlaenge);
36
    Serial.print(" Char Pointer *s: ");Serial.print(*s);// *s ist die jeweilige Buchstabe
37
    Serial.print(" : ");
38
    Serial.print(" Scrolltext string s: ");Serial.println(s);// Der ganze übrige string 
39
    if (*s < 32) { Serial.println(" c<32 return "); return; } // im Fehlerfall
40
    stringlaenge--;
41
    s++;// Pointer auf nächste Char im String
42
   }
43
    displaychar = zeitstempel;
44
  }
45
  // WEITERE PROGRAMMANWEISUNGEN
46
}  //----------------------------Loop Ende----------------------------

DANKE!

von Markus F. (mfro)


Lesenswert?

laß' das "char *" vor "s=..." im inneren Block einfach weg. Damit ist 
das keine Deklaration mehr, sondern eine simple Zuweisung an die global 
definierte Variable.

Und kaum macht man's richtig, schon geht's...

von Oliver S. (oliverso)


Lesenswert?

...und kauf dir endlich ein C-Buch, oder auch dir ein Tutorial im Netz. 
Mit Trail and Error wird das nichts, wie man an deinen Beiträgen 
erkennt. Du hast dein Problem bisher nicht mal ansatzweise verstanden.

Im Kapitel deiner Wahl im C-Buch sollte was zum den Gültigkeitsbereich 
(oder englisch:Scope) von Variablen stehen.

Oliver

: Bearbeitet durch User
von Bauteiltöter (Gast)


Lesenswert?

Bauteiltöter schrieb:
> STK500-Besitzer schrieb:
>> Johann L. schrieb:
>>> Das in *s stehende Zeichen wird als Adresse eines Strings interpretiert.
>>
>> Nö. Damit wird der Inhalt einer Speicherstelle zurückgeliefert - also
>> ein Buchstabe/Zeichen.
>
> Genau. und dieser Buchstabe/Zeichen wird dann an eine FUnktion
> übergeben, die die Adresse eines Strings haben will!

Ok, ich muss mich korrigieren. Es geht ja nicht um C, sondern um C++.
Serial.print() gibt es 4x, eine Version für int, eine für float, eine 
für char und eine für char*.

das serial.print(*s) ist also korrekt und wird auch keine Warnung 
erzeugen.

von JoJoBa (Gast)


Lesenswert?

@mfro
....mensch Markus, Du hast mir am Anfang die Lösung verraten,
ich habe es aber nicht richtig interpretiert.....
DANKE für den Hinweis, ich verstehe jetzt zwar noch
immer nicht ganz, aber die Lösung ist wie Du sagst!

ich darf es nicht immer wieder neu Deklarieren!!!

in der Zwischenzeit habe ich mein Problem auf andere weise mit
Feldindizes gelöst, das will ich aber nicht einsetzen.
In meinem Selbststudium bin ich seit 2 Wo bei den Pointers
strings und arrays angelangt und erst jetzt habe angefangen
verschiedene Aufgaben lösen zu wollen....
und bin bei diesem Stolperstein stehengeblieben.

Danke auch für andere schlaue Vorschläge mit Büchern und sooo,
aber das ist längst im Gange, nur halt über 50 rattert ja die
Festplatte nicht so mit 15000rpm :-)....wie früher

möchte trozdem noch hier die andere Variante posten, vielleicht
hilft es doch jemanden anderen....
1
// Textausgabe Buchstabenweise
2
char str[]="TestTEXT";
3
int stringlaenge=strlen(str); 
4
int i=0;
5
6
  void setup(){
7
  Serial.begin(19200);
8
  Serial.print(" Stringlaenge ");
9
  Serial.println(stringlaenge);//
10
  
11
  Serial.println(" Programm stertet..... ");
12
  delay(1000); 
13
  
14
}
15
//--------------------------------------------------------
16
void loop() {   
17
  
18
  Serial.println(" ---------------neues Loop ----------- ");
19
   
20
  if(stringlaenge==0) {
21
    Serial.println(" Stringlaenge wird neu ermittelt------------------------ ");
22
    stringlaenge=strlen(str);
23
    i=0;
24
   }
25
  if(stringlaenge != 0)
26
  {
27
    Serial.print(" StringLaenge= ");Serial.println(stringlaenge);
28
    Serial.print(" Char Pointer *s: ");Serial.print(str[i]);// *s ist die jeweilige Buchstabe
29
    Serial.print(" : ");
30
    Serial.print(" Scrolltext string s: ");Serial.println(str);// Der ganze übrige string 
31
    stringlaenge--;
32
    i++;// Index auf nächste Char im String
33
    delay(1000);
34
   }
35
  delay(500);
36
}  //----------------------------Loop Ende----------------------------

Markus, vielen Dank für den richtigen Hinweis!!!!

>> Man kommt nicht durch Wollen,Hoffen,Wünschen voran, sondern durch
   Absichten <<
Gruß, csaba und DANKE euch ALLEN!

von JoJoBa (Gast)


Lesenswert?

Sorry, aber eine Verständnissfrage bleibt mir immer noch;

Am Anfang habe ich den Code mit  while Schleife gepostet
und auf mein Problem hingewiesen.

In dem main Loop gibt es die zeile mit dem Pointer:
 char* s=string;
danach
 while Schleife
danach
 kehre zurück zum loop Anfang,

und diese Reihenfolge funktioniert reibungslos!

Ändere ich im main loop die Anweisungen so, dass ;
 while-Schleife
danach
 char* s=string;
danach
 ende vom loop, kehre zurück zum Anfang

dann habe ich nur 1xTextdurchlauf, und dann ist schluss.
Der Loop schleift weiter um sich hin ohne die Buchstaben auszugeben.

Warum kommt es zu diesem Verhalten?

Und seit 2 Wochen recherchiere ich im web über Pointer und
Tausende andere Dinge, aber fand bisher keine Erklärung.
die angeblich wiederholte Deklaration
  char* s=string;
kommt in beiden Codevarianten gleich vor!

Gruß!

von Rolf M. (rmagnus)


Lesenswert?

JoJoBa schrieb:
> DANKE für den Hinweis, ich verstehe jetzt zwar noch
> immer nicht ganz, aber die Lösung ist wie Du sagst!

Was ist denn unklar? Ist doch eigentlich ganz einfach:
1
if(stringlaenge==1) {
2
    Serial.println(" Stringlaenge wird neu ermittelt------------------------ ");
3
    char* s=string;  // Zeige auf den ersten char im string
4
    stringlaenge=strlen(string)+1;
5
   }

Du erzeugst in diesem if-Block eine Variable namens s. Nach dem Ende des 
Blocks hört diese Variable auf zu existieren. Und diese Variable hat 
nichts, aber auch gar nichts mit dem s zu tun, das du am Anfang des 
Programms definierst. Es sind zwei komplett separate Variablen.

Das s, das du hier verwendest, ist allerdings das global definierte s:
1
if ((zeitstempel - displaychar) >= zeitfenster)
2
{
3
  if (*s != 0)// solange die Nullterminierung am Ende vom string erreicht wird...
4
  {
5
   Serial.print(" StringLaenge= ");Serial.println(stringlaenge);
6
   Serial.print(" Char Pointer *s: ");Serial.print(*s);// *s ist die jeweilige Buchstabe
7
   Serial.print(" : ");
8
   Serial.print(" Scrolltext string s: ");Serial.println(s);// Der ganze übrige string
9
   if (*s < 32) { Serial.println(" c<32 return "); return; } // im Fehlerfall
10
   stringlaenge--;
11
   s++;// Pointer auf nächste Char im String
12
  }
13
   displaychar = zeitstempel;
14
 }

von JoJoBa (Gast)


Lesenswert?

@rmagnus
Ok, ich glaub ich kapiere es jetzt!
Die Variable mit dem Typ char habe ich am Anfang deklariert
und auch Initialisiert als global!
..damit überall im Code verwendbar wird.

In der if....Anweisung habe sie aber wieder
deklariert und initialisiert.
Dabei war die Deklaration hier falsch;
ich muss sie nur neu Initialisieren, damit sie (die Gleiche!)
mir als Pointer auf den ersten char im string zeigt!

ich Verstehe es jetzt!
Suuuper, DANKE!!!!

von Klaus (Gast)


Lesenswert?

@ JoJoBa

Da die meisten hier diesen Punkt mehr oder weniger sofort gesehen haben, 
eine Deklaration mitten im Code ist eher ungewöhnlich -, kannst Du davon 
ausgehen, dass das eine grundlegende Sache ist. (Es sei zugegeben, dass 
auch dazu eine gewisse Praxis gehört).


Dazu solltest Du einfach mal ein C-Buch lesen. Und dann noch lernen, 
worin bei Arduino die Besonderheiten bestehen, aufgrund deren Du anders 
vorgehen muss als "der Rest der Welt".

Ein Debugger wäre gut.
Übrigens hättest Du Dir im AVR-Studio im Simulator das genaue Problem 
einmal anschauen können.

Na ja. Noch ist es nicht zu spät. :-)

von JoJoBa (Gast)


Lesenswert?

@Klaus,
Du sprichst natürlich die Schokoladenseite an....
ich stecke erst beim Arduino IDE und studiere die
pdf. fach-Geschenke aus dem web mit mal kleinerem mal größerem
Erfolg.
Neben einem Beruf ist diese Tätigkeit mein Hobby geworden
aber ich will nicht aufgeben, und befor mich die Frustration
packen würde, greife ich zum Internetportal, wie dieser hier...

Es kann sein dass ich damit einige Leuchte abschrecke, oder gar
verärgere, aber das ist natürlich nicht mein Absicht!

Möchte auf jedem Fall die Hilfebereitschaft von euch Allen loben,
und wünsche Jedem weiterhin viel Erfolg!!!!

Gruß,
csaba

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.