Kurze Frage zu char*

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

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

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

char line[10];

Dann kannst Du "line" auch als "char*" Typ verwenden. Alternativ kannst Du auch mittels

char* line;
line = malloc(10);

den notwendigen Speicher (ich hab im Beispiel immer 10 Bytes genommen) reservieren.

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

nein, das brauchst Du nicht. In C können char[] und char* quasi synonym verwendet werden.
Wenn Du ein

//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

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.

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

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

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 avr-libc: <stdlib.h>: General utilities) liefert eigentlich ein char* (also 16 Bit Pointer) zurück.

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