Pages: [1]   Go Down
Author Topic: Kurze Frage zu char*  (Read 646 times)
0 Members and 1 Guest are viewing this topic.
Mönchengladbach, Germany
Offline Offline
Full Member
***
Karma: 6
Posts: 140
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ich habe folgenden Zeilen geschrieben und wundere mich nun, warum nichts ausgegeben wird.

Code:
float Temp;
char* line;


void setup(){
 Serial.begin(9600);
}
void loop()
{
  Temp = 22.5,
  dtostrf(Temp, 5, 2, line);
  Serial.println(line);

delay(10000);
}

Das Ergebnis der Umwandlung sollte doch in dem character-array 'line' stehen. Ich kann vermutlich nichts sehen, weil ich einen String zur Anzeige benötige. Das Thema char* will einfach nicht in meinen Kopf.

Eberhard
Logged

Oscar Wilde: "Am Ende wird alles gut, und wenn es noch nicht gut ist - ist es nicht das Ende."  

Offline Offline
Edison Member
*
Karma: 21
Posts: 1419
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Das Ergebnis der Umwandlung sollte doch in dem character-array 'line' stehen.
Das ist richtig, nur hast Du kein Character-Array erstellt. Deine Variable "line" enthält nämlich nur einen Zeiger auf ein Chracter-Array, nicht das Array selbst.

Entweder machst Du einfach ein
Code:
char line[10];

Dann kannst Du "line" auch als "char*" Typ verwenden. Alternativ kannst Du auch mittels
Code:
char* line;
line = malloc(10);
den notwendigen Speicher (ich hab im Beispiel immer 10 Bytes genommen) reservieren.
Logged

Mönchengladbach, Germany
Offline Offline
Full Member
***
Karma: 6
Posts: 140
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Wenn ich Dich richtig verstanden habe, ist das die Einstiegsadresse. In der Speicherstelle und denen dahinter steht das Ziel meiner Begierde. Wie kann ich die denn so auslesen, dass ich den String in Serial.print() anzeigen kann?  Ich würde die Speicherstellen solange inkrementieren, bis ich auf ein '\0'-Zeichen stoße.

dazu müsste ich ersteinmal die erste Stelle auslesen können. Danach:

//1.Speicherstelle auslesen (keine Ahnung wie das geht)
??????
String Ergebnis = Inhalt(line);

While  (!Inhalt(line)=='\0')
{
   ++line;
   Ergebnis += Inhalt(line);

}


Das ist bewusst nur ein Pseudocode, um Dir meine Vorgehensweise zu zeigen.

Eberhard


Logged

Oscar Wilde: "Am Ende wird alles gut, und wenn es noch nicht gut ist - ist es nicht das Ende."  

Offline Offline
Edison Member
*
Karma: 21
Posts: 1419
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

nein, das brauchst Du nicht. In C können char[] und char* quasi synonym verwendet werden.
Wenn Du ein
Code:
//definiere ein Array mit 25 Zeichen (24 können für den String verwendet werden, 25. für \0)
char meinString[25] = "ich bin der Text";
// (fast) identisch ist:
char* meinString2 = "Ich bin der Text 2";
definierst, kannst Du einfach ein
Code:
Serial.println(meinString);
//bzw.
Serial.println(meinString2);
machen und der String wird ausgegeben. Dabei wird die Nullterminierung automatisch beachtet.

Dein ursprüngliches Problem war, das Du NUR den Adresspointer definiert hast, aber nicht den Speicherbereich, der dann die eigentlichen Daten aufnimmt.
Der Funktion dtostrf() ist das aber wurscht, die schreibt ab der Adresse in den Speicher und überschreibt dabei vermutlich andere Variablen Deines Programms die im Speicher hinter Deinem Pointer liegen.

Abgesehen davon, sehe ich gerade das Dein Sketch noch nicht mal compilieren dürfte, da Du hinter
Temp = 22.5,
ein Komma statt eines Semikolon steht.
Hast Du den originalen Sketch gepostet der nichts anzeigt, oder ist das nur ein Beispiel gewesen?
Mario.
Logged

Mönchengladbach, Germany
Offline Offline
Full Member
***
Karma: 6
Posts: 140
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

So, jetzt läuft es. Hier der neue Originalcode:

Code:
float Temp;
char* line = "Musterstring";


void setup(){
 Serial.begin(9600);
}
void loop()
{
  Temp = 77.3,
  dtostrf(Temp, 6, 2, line);
  Serial.println(line);

delay(10000);
}

Ich habe jetzt einen Speicherbereich über den "Musterstring" zugewiesen, der ja nachher wieder überschrieben wird. Bei den Parametern (Temp, 5, 2, line) musste ich die 5 erhöhen, da nur die erste Stelle vor dem Komma angezeigt wurde. Kannst Du Dir vorstellen warum? Selbst wenn da noch ein nicht sichbares zeichen drin ist, müsste das doch ausreichen.

Der Code oben ist der Originalcode per copy/paste. Jetzt kommt's: Das Komma an dieser Stelle funktioniert. Ich habe es extra mal dringelassen. Kein Fehler beim Compilieren.. Ich glaube die String-Operationen sind schon etwas schwierig zu verstehen.

Vielen Dank für Deine Extra-Schulung.

Eberhard
Logged

Oscar Wilde: "Am Ende wird alles gut, und wenn es noch nicht gut ist - ist es nicht das Ende."  

Offline Offline
Edison Member
*
Karma: 21
Posts: 1419
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Das Der Code mit dem Komma funktioniert ist "Zufall", denn vermutlich interpretiert der Compiler die nachfolgende Zeile mit dem dtostrf() zur Zeile Temp = 77.5, dazu.
Setzt man nämlich ein syntaktisch korrektes "int i = 0;" zwischen die Zeilen, meckert der Compiler.

Das nur der Vollständigkeit halber. Keine Ahnung welche Seiteneffekte Dein Code mit dieser "Pseudozuweisung" auslöst, da Temp ja eigentlich ein float und die dtostrf() der AVR LibC (siehe http://www.nongnu.org/avr-libc/user-manual/group__avr__stdlib.html) liefert eigentlich ein char* (also 16 Bit Pointer) zurück.
Logged

Mönchengladbach, Germany
Offline Offline
Full Member
***
Karma: 6
Posts: 140
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ein nützlicher und lehrreicher Exkurs in die Welt der Strings und char's. Hoffentlich nicht nur mich, sondern für Viele hier im Forum.

Dir, mkl0815, meinen herzlichen Dank.

Eberhard

Logged

Oscar Wilde: "Am Ende wird alles gut, und wenn es noch nicht gut ist - ist es nicht das Ende."  

Pages: [1]   Go Up
Jump to: