invalid conversion from 'const char*' to 'char*'

Hi,

ich habe folgendes Problem.
Der Compiler meldet folgenden Fehler:

exit status 1
invalid conversion from 'const char*' to 'char*' [-fpermissive]

Ich möchte ein Array mit 7 Variablen haben, das habe ich so definiert:

char *textcol[7];   // Array Variable für Textfarbe aus JSON

Die Variable möchte ich folgendermaßen befüllen:

textcol[1] = rgb565(userData->color));

Die Funktion rgb565 sieht folgendermaßen aus:

uint16_t rgb565(char str[])
{
  unsigned long rgb = strtoul(str + 1, NULL, 16);  // String in Integer wandeln
  uint16_t R = (rgb >> 16) & 0xFF;
  uint16_t G = (rgb >>  8) & 0xFF;
  uint16_t B = (rgb      ) & 0xFF;
  uint16_t ret  = (R & 0xF8) << 8;  // 5 Bits
           ret |= (G & 0xFC) << 3;  // 6 Bits
           ret |= (B & 0xF8) >> 3;  // 5 Bits
  return( ret);
}
struct UserData {
  char color[7];   // Der HEX Farbwert ist im JSON als String mit 7 Stellen gespeichert
};

Ich hoffe ich habe nichts wichtiges vergessen?

Wo liegt der Fehler?
Wie müsste der Code korrekt aussehen?

Lieben Danke und lieben Gruß,
Chris

Hallo,

anlegen würde ich ein Array immer ohne Zeiger. Ich würde auch byte statt char verwenden.

Google mal nach "c struct".

Bei der Fehlermeldung steht auch immer die Zeilennummer dabei, da sollte man zuerst hinschauen.
Wenn man keine Tabs verwendet, stimmt die auch zu 99,999% der Fälle.
Verwendet man Tabs in der IDE kann man diese Angabe vergessen.
Dann hilft nur an der Stelle zu suchen wo man zuletzt rumgefummelt hat.

Hi Doc_Arduino,

Vielen Dank für deine Antwort.
Leider verstehe ich nur Bahnhof. Bin blutiger Arduino Anfänger. Hab zwar vor vielen Jahren einiges in anderen Programmiersprachen gecoded, aber Arduino bzw. C is mir leider noch sehr fremd. Da muss ich noch viel lernen.

Wie müsste denn der Code korrekt aussehen?

Lieben Gruß,
Chris

also char *textcol[7]; ohne *
Dann int weil Du ein Int in der Funktion zusammenbaust:

uint16_t textcol[7];

Andere Fehler können wir aus Mangel am Wissen des gesamten Sketches nicht sehen.

Grüße Uwe

char* array[] ist ein Array aus Zeigern. Das brauchst du wenn du ein Array aus C Strings willst
char array[] ist ein C String.

Array Variablen sind Zeiger auf das erste Element. Das ist der Grund weshalb ein Array aus Arrays aus ein Array aus Zeigern ist.

Wie Uwe sagt willst du aber eigentlich ein Array aus Integern!

textcol[1] = rgb565(userData->color));

Hier ist eine Klammer zu viel. Das sollte aber auch einen Fehler produzieren. Auch etwas seltsam ist das userData hier wohl ein Zeiger ist. Das ist zwar nicht zwangsläufig falsch, aber wenn du das per Variable an ein Funktion übergibst, wäre eine Referenz einfacher

uint16_t rgb565(char str[])
{ }

Hier ist es üblicher einen const char* als Parameter zu übergeben. Du willst einen C String als Parameter übergeben. Ist aber nicht unbedingt falsch

Hmm, mein Problem mit den Antworten ist, dass ich sie leider noch nicht verstehe, weil ich mich damit nicht auskenne :frowning:
Ich krieg's einfach nicht hin :frowning:
Ich extrahiere mal die relevanten Zeilen aus meinem zusammenkopierten und umgeschriebenen 700 Zeilen Listing:

uint16_t textcol[7];   // Array Variable für Textfarbe aus JSON

struct UserData {
  char color[7];
};

uint16_t rgb565(char str[])
{
  unsigned long rgb = strtoul(str + 1, NULL, 16);  // String in Integer wandeln
  uint16_t R = (rgb >> 16) & 0xFF;
  uint16_t G = (rgb >>  8) & 0xFF;
  uint16_t B = (rgb      ) & 0xFF;
  uint16_t ret  = (R & 0xF8) << 8;  // 5 Bits
           ret |= (G & 0xFC) << 3;  // 6 Bits
           ret |= (B & 0xF8) >> 3;  // 5 Bits
  return( ret);
}


for (int i=0; i<7; i++){
  textcol[i] = rgb565(userData->color);    // Nur zum Testen in alle Variablen den gleichen Wert schreiben
}

userData->color ist gefüllt mit #009933

Es kommt immernoch der Fehler:
"invalid conversion from 'const char*' to 'char*' [-fpermissive]"

Das muss doch hinzukriegen sein.
Kann mir vielleicht nochmal jemand helfen?

Danke und liebe Grüße,
Chris

userData->color ist gefüllt mit #009933

Vorsicht Fehler! Das sind 7 Zeichen. Das heißt dein Array muss 8 groß sein. Nicht 7. C Strings sind Null-terminiert. An der letzten Stelle steht NULL, bzw. '\0' um das Ende zu kennzeichnen. Solche Arrays müssen immer mindestens 1 größer als die Anzahl der sichtbaren Zeichen sein

700 Zeilen sind nicht viel. Das kannst du als Anhang komplett posten.

Bei den Code Schnippseln würde ich mal den Parameter bei rgb565(...) von von char[] auf const char* ändern. Das bedeutet ein Zeiger auf einen konstanten String und ist in C die übliche Art einen String zu übergeben der von der Funktion nicht verändert wird.

Ansonsten ist nicht ersichtlich was nicht passt. Es würde wie gesagt mal helfen wenn du sagst ein welcher Zeile der Fehler kommt.

Hallo,

ich vermute, der Code ist "nur" zusammenkopiert. Mit Arrays und Strukturen musst du dich dennoch selbst auch befassen, sonst verstehst du nie deinen eigenen Code. Also wenn dann musste schon den kompletten Code zur Verfügung stellen. Die Erfahrung lehrt, dass der Fehler nie dort steckt wo man ihn vermutet. Wenn der Code zu lang sein sollte zum reinkopieren, dann häng die .ino ran.

Vielen Dank für die Unterstützung!

Vorsicht Fehler! Das sind 7 Zeichen. Das heißt dein Array muss 8 groß sein.

Das probier ich mal.

Bei den Code Schnippseln würde ich mal den Parameter bei rgb565(...) von von char[] auf const char* ändern.

Das hatte ich schon probiert, dann gibt's den nächsten Fehler :frowning:

Im Anhang das komplette Programm. Ich dachte bei 700 Zeilen ist es zuviel verlangt sich da reinzufuchsen. Da sind auch noch ne Menge überflüssige Zeilen drinnen. Ist halt noch in der Entwicklung.

Lieben Gruß,
Chris

[EDIT] Password aus angehängter Sketch entfernt Uwe[/EDIT]

Anzeige ohne PW.ino (22.8 KB)

Ja, das ist sicherlich Copy/Paste und dann versucht Sachen zu ändern ohne zu verstehen was abläuft.

Wo du dich mal entscheiden musst ist welches Format dein String hat. In rgb565() machst du +1 um ein '#' davor zu überspringen. In readReponseContent() ist das aber nicht der Fall. Wobei Test-Ausgaben in der Funktion auch gar nichts verloren haben. Die Ausgabe der Daten erfolgt in printUserData()

Das probier ich mal.

Ist aber nicht die Lösung für den eigentliches Problem. Das ist ein Fehler über den sich der Compiler nicht beschweren kann. Bei solchen Pufferüberläufen treten erst zur Laufzeit Merkwürdigkeiten auf.

Auch der Fehler wird dadurch gekommen sein, dass der ursprüngliche Sketch kein '#' vorgesehen hat. Bzw. dass der Haupt-Sketch und die Konvertierungsfunktion aus zwei verschiedenen Quellen stammen

Das hatte ich schon probiert, dann gibt's den nächsten Fehler

Sollte aber laut Code funktionieren. Mit const char* kann man sowohl Arrays übergeben als auch String Literale. Also du könntest auch testweise direkt das schreiben:

... = rgb565("#001122");

Ja, das ist sicherlich Copy/Paste und dann versucht Sachen zu ändern ohne zu verstehen was abläuft.

Ja sicher Copy/Paste! :slight_smile:
Asche auf mein Haupt :slight_smile:
So hab ich vor 25 Jahren auch Basic, Turbo Pascal und Visual Basic autodidaktisch gelernt. Aber da hatte ich auch viel Zeit.
....und das ist auch schon lange her :slight_smile:

Das funktioniert:

textcol[i] = rgb565("FFAA22");  // ich hab die Farbe mal etwas heller gemacht, 001122 ist schon sehr dunkel ;-)

Wo du dich mal entscheiden musst ist welches Format dein String hat.

.... keine Ahnung :frowning:
Das kommt aus einem JSON mit folgendem Inhalt (die Variable "color":"#009933"):

{"version":"0.3","entity":{"uuid":"05ce3700-97c7-11e6-acf4-754d9577033c","type":"temperature","active":false,"color":"#009933","fillstyle":0,"public":true,"style":"lines","title":"T01 Aussen","yaxis":"auto"}}

Das JSON wir mit der Funktion readReponseContent(struct UserData* userData) ausgelesen.
Die Variable, in der die Information gespeichert wird ist so deklariert:

struct UserData {
  char color[7];   // Der HEX Farbwert ist im JSON als String mit 7 Stellen gespeichert
};

Demnach müsste es doch ein char sein. (ich weiss nur wie es heisst, aber ich kann nicht behaupten, dass ich weiss was das ist. In den Sprachen die ich kenne ist das ein String. Asche auf mein Haupt.

Auch der Fehler wird dadurch gekommen sein, dass der ursprüngliche Sketch kein '#' vorgesehen hat. Bzw. dass der Haupt-Sketch und die Konvertierungsfunktion aus zwei verschiedenen Quellen stammen

Ja klar, wenn das einer besser kann, dann immer her damit :slight_smile:

Lieben Gruß,
Chris

Sollte aber laut Code funktionieren. Mit const char* kann man sowohl Arrays übergeben als auch String Literale.

Wo soll das genau stehen?
Ich hab

uint16_t rgb565(const char* str[])

probiert.
Das geht nicht?!

Lieben Gruß,
Chris

uint16_t rgb565(const char* str[])

Oh je. Was sollen da noch die Array Klammern? Das ist ein Array aus Zeigern

So:

uint16_t rgb565(const char* str)

Ein Zeiger auf char

Demnach müsste es doch ein char sein.

Ein char ist ein Byte mit Vorzeichen. In C sind Strings keine eigenen Datentypen sondern ein Array aus char mit einem NULL am Ende. Wenn du also 7 Zeichen hast, muss das Array 8 groß sein. Wenn das nicht der Fall ist wird einfach über das Ende hinaus geschrieben.

C Strings sind sehr fehleranfällig (weshalb es in Standard C++ auch std::string als Klasse wie in anderen Sprachen gibt), aber auch relativ sparsam an Speicher und sehr mächtig. Deshalb sind sie bei kleinen µC mit wenig RAM die beste Wahl

Dann musst du noch den Zusammenhang zwischen Arrays und Zeigern verstehen. Eine Array Variable ist nur wenig mehr als ein Zeiger auf das erste Element. Also die Adresse an der das Array anfängt. Wenn man also Arrays an Funktionen übergibt, übergibt man i.d.R. einen Zeiger. Deshalb const char*

Das kommt aus einem JSON mit folgendem Inhalt (die Variable "color":"#009933"):

Dann muss dein Array 8 Zeichen groß sein

Hier wird dann das '#' am Anfang übersprungen:

unsigned long rgb = strtoul(str + 1, NULL, 16);

Man addiert 1 auf die Adresse. Dadurch fängt die Konvertierung beim zweiten Zeichen an

Hallo,

mir fällt es schwer den Durchblick zubekommen. Helfen werde ich da nicht können, da muss ich ehrlich zu mir und zu dir sein. Vielleicht erstmal alle maximalen Array und String Längen ermitteln und die Größen anpassen. Lieber größer als klein.

Eine Info am Rande. Vorm posten das Router Login rausnehmen.
Noch ein allgemeiner Tipp falls nichts vorwärts geht. Code aufräumen und zur Fehlersuche immer weiter abspecken. Also in Teilprobleme zerlegen. Erstens lernt man was der Code macht und zweitens findet man seine Fehler. Oder erstmal kleiner anfangen. Jede verwendete Lib wird eigene Bsp. haben.

mir fällt es schwer den Durchblick zubekommen.

Das dachte ich mir, deswegen hatte ich ja nur den relevanten Code extrahiert.

Vorm posten das Router Login rausnehmen.

Der ist natürlich geändert / nicht der richtige.

Noch ein allgemeiner Tipp falls nichts vorwärts geht. Code aufräumen und zur Fehlersuche immer weiter abspecken. Also in Teilprobleme zerlegen. Erstens lernt man was der Code macht und zweitens findet man seine Fehler. Oder erstmal kleiner anfangen. Jede verwendete Lib wird eigene Bsp. haben.

So gehe ich immer vor. Das hier ist ja bereits relativ weit fortgeschritten. Das ist schon aus mehreren lauffähigen Einzelprogrammen ein großes Zusammengewachsen. Nun geht es halt an die Schritte, die nur noch im Verbund funktionieren.

Oh je. Was sollen da noch die Array Klammern? Das ist ein Array aus Zeigern

Genau das war die Lösung. so einfach kann es sein.
Nun läuft's und ich kann weitermachen.
Wenn es läuft wird es noch verschlankt und die ganzen überflüssigen Zeilen kommen raus.
Vielen Dank dafür!
Lieben Gruß,
Chris

Sowas sieht man leider sehr oft in Anfänger Beispielen:

uint16_t rgb565(char str[])

Das ist nicht unter allen Umständen falsch! Es gibt Fälle wo man Array besser so übergibt (auch mit Angabe der Länge in den Klammern). Aber nicht wenn es ganz allgemein sein muss. Und ganz und gar nicht wenn die Arrays Strings sind.

Man will Anfängern da einen Gefallen tun und die Zeiger verstecken. Aber praktisch provoziert man sehr wahrscheinlich zukünftige Fehler wenn die Funktion mal etwas anders verwendet wird.
Auch auf const-Korrektheit wird leider kaum geachtet. Das zu ignorieren produziert manchmal Warnungen die man ignorieren kann, aber u.U. auch Fehler.

Besser man macht es gleich richtig :slight_smile:

themanfrommoon:
Hmm, mein Problem mit den Antworten ist, dass ich sie leider noch nicht verstehe, weil ich mich damit nicht auskenne :frowning:
Ich krieg's einfach nicht hin :frowning:
Ich extrahiere mal die relevanten Zeilen aus meinem zusammenkopierten und umgeschriebenen 700 Zeilen
...

Es kommt immernoch der Fehler:
"invalid conversion from 'const char*' to 'char*' [-fpermissive]"

Das muss doch hinzukriegen sein.
Kann mir vielleicht nochmal jemand helfen?

Danke und liebe Grüße,
Chris

Wieder der falsche Ansatz.
Du gibst uns eine Fehlermeldung ohne Zeilenangabe.
Du gibst uns einen nicht lauffähigen Sketch den wir nicht kompilieren können um den Fehler zu finden.
Wir können nicht hellsehen und hageb auch keine Kristallkugen zu verfügung um Dein Problem zu erraten.
Darum den ganzen Sketch (auch als Anlage) und link an die Bezugsquellen der verwendeten Bibliotheken.

Grüße Uwe

Moin Uwe,

das Problem ist doch schon gelöst, siehe Post #12. Das Problem waren die Array Klammern.
Das gesamt Sketch habe ich in Post #8 angehängt.
Die SSID und das Passwort im Sketch hatte ich bereits verfälscht.

Danke nochmal für die freundliche Hilfe!

Liebe Grüße,
Chris