Arduino Forum

International => Deutsch => Topic started by: ArdunioArti on Dec 30, 2019, 04:53 pm

Title: Char trennen und in int umwandeln
Post by: ArdunioArti on Dec 30, 2019, 04:53 pm
Hallo,

für mein Projekt möchte ich Daten von einer SD Karte auslesen und dann verschiedenen Variablen zuweisen.
Das Auslesen funktioniert soweit auch schon, allerdings bekomme ich die Daten nicht getrennt. Als Trennzeichen habe ich ; verwendet.
Der Sketch sieht folgendermaßen aus.
Code: [Select]
    char Einstellungen;
    byte _sentencePos = 0;
    byte _comma_count = 0;
    char msg_field ;

void setup() {

  while (!Serial);               
  Serial.begin(9600);
 
  Einstellungen = "1;5;30;";

}

void loop() {



    for (int i=0; i<=7; i++)
    {
 
        if (Einstellungen[_sentencePos] == ';')
        {
            _comma_count++;
       //    msg_field[_comma_count] = "";
            _sentencePos++;
        }
        else
        {
            msg_field[_comma_count] += Einstellungen[_sentencePos];
            _sentencePos++;
        }
    }


Serial.println(Einstellungen);   
Serial.println(msg_field[0]);
Serial.println(msg_field[1]);
Serial.println(msg_field[2]);

delay(10000);
}


Es wird folgender Fehler angezeigt.
Arduino: 1.8.10 (Windows 10), Board: "Arduino/Genuino Uno"

Char_trennen:4:5: error: 'msg_field' does not name a type

     msg_field[_comma_count] = "";

     ^~~~~~~~~

C:\Users\XXX\Documents\Arduino\Char_trennen\Char_trennen.ino: In function 'void setup()':

C:\Users\XXX\Documents\Arduino\Char_trennen\Char_trennen.ino:11:19: warning: invalid conversion from 'const char*' to 'char' [-fpermissive]

   Einstellungen = "1;5;30;";

                   ^~~~~~~~~

C:\Users\XXX\Documents\Arduino\Char_trennen\Char_trennen.ino: In function 'void loop()':

Char_trennen:22:39: error: invalid types 'char[byte {aka unsigned char}]' for array subscript

         if (Einstellungen[_sentencePos] == ';')

                                       ^

Char_trennen:30:13: error: 'msg_field' was not declared in this scope

             msg_field[_comma_count] += Einstellungen[_sentencePos];

             ^~~~~~~~~

Char_trennen:30:66: error: invalid types 'char[byte {aka unsigned char}]' for array subscript

             msg_field[_comma_count] += Einstellungen[_sentencePos];

                                                                  ^

Char_trennen:37:16: error: 'msg_field' was not declared in this scope

 Serial.println(msg_field[0]);

                ^~~~~~~~~

exit status 1
'msg_field' does not name a type

Dieser Bericht wäre detaillierter, wenn die Option
"Ausführliche Ausgabe während der Kompilierung"
in Datei -> Voreinstellungen aktiviert wäre.


Es scheint also das Format des Chars nicht zu stimmen, aber genau werde ich daraus nicht schlau.

Vielen Dank schonmal für Eure Hilfe.
Title: Re: Char trennen und in int umwandeln
Post by: Serenifly on Dec 30, 2019, 05:12 pm
Das muss man nicht per Hand machen. Schau dir strtok() und atoi() an

Andererseits musst du erst mal lernen wie C Strings funktionieren. Ein char ist ein Zeichen. Natürlich kannst du dem keinen String zuweisen. C Strings sind Null-terminierte Arrays aus char
Title: Re: Char trennen und in int umwandeln
Post by: combie on Dec 30, 2019, 05:17 pm
Quote
char Einstellungen;
Hier ist Einstellungen genau 1 Byte groß.
Und definitiv kein Array.


Quote
Einstellungen[_sentencePos] == ';'
Hier behandelst du es wie ein Array.

Das gleiche gilt für msg_field.


Title: Re: Char trennen und in int umwandeln
Post by: Rentner on Dec 30, 2019, 05:47 pm
Hallo,

schau mal hier Wiki (https://de.wikibooks.org/wiki/C-Programmierung:_Zeichenkettenfunktionen)

Heinz
Title: Re: Char trennen und in int umwandeln
Post by: ArdunioArti on Dec 30, 2019, 05:49 pm
Jetzt bin ich etwas verwirrt. In einem anderen Beitrag wurde mir folgendes empfohlen
Wenn der RAM knapp ist, (beim UNO mit SD) sollte man zunächst auf String und andere dynamische Speicherfresser verzichten.

Ich war der Meinung, dass es sich bei string um einen Datentyp handelt, den ich durch ein Array aus char ersetzen kann um Ram zu sparen.
Jetzt habe ich mich aber nochmal ein wenig eingelesen und hier (http://arduino-pilot.blogspot.com/2013/08/datentypen.html) steht, dass ein String auch nur ein Array des Datentyps char ist.

Und was ist dann ein C String ?

Title: Re: Char trennen und in int umwandeln
Post by: combie on Dec 30, 2019, 05:53 pm
Quote
, dass ein String auch nur ein Array des Datentyps char ist.
String ist eine recht umfangreiche Klasse.
Ihr Laufzeitverhalten kann dir Streiche spielen.


Ein C-string wohnt in einem char Array.
Einzige Besonderheit: Ein C-string endet mit einer '\0'
Title: Re: Char trennen und in int umwandeln
Post by: ArdunioArti on Dec 30, 2019, 05:57 pm
Hier ist Einstellungen genau 1 Byte groß.
Und definitiv kein Array.
Ich dachte durch
Einstellungen = "1;5;30;";
wird Einstellungen erweitert.

Ursprünglich wollte ich Einstellungen folgendermaßen definieren. (20 Zeichen für maximale Einstellungen)
char Einstellungen[20];

Dann hatte ich aber ein Problem mit
Einstellungen = "1;5;30;";

Warum kann ich in diesem Fall Einstellungen nicht füllen.


Title: Re: Char trennen und in int umwandeln
Post by: Tommy56 on Dec 30, 2019, 06:05 pm
Einstellungen ={1,5, 30} ; als Charwerte

Gruß Tommy
Title: Re: Char trennen und in int umwandeln
Post by: Serenifly on Dec 30, 2019, 06:08 pm
Du musst Grundlagen lernen. Array-Variablen sind in C/C++ nicht viel mehr als Zeiger auf das erste Element. Daher kann man denen nicht einfach Inhalte zuweisen. Das geht so nur bei direkt der Initialisierung.

Das geht:
Code: [Select]

char Einstellungen[20] = "1;5;30;";

Aber das ist eben keine Zuweisung, sondern eine Initialisierung. Auch wenn es gleich aussieht

Quote
(20 Zeichen für maximale Einstellungen)
19 sichtbare Zeichen + Null-Terminator
Title: Re: Char trennen und in int umwandeln
Post by: combie on Dec 30, 2019, 06:13 pm
Quote
Ich dachte durch
Einstellungen = "1;5;30;";
wird Einstellungen erweitert.
Tolle Idee,  kannste aber knicken.

Die automatische Erweiterung ist ja gerade das Problem bei String, deswegen ja die C-strings



Dann hatte ich aber ein Problem mit
Einstellungen = "1;5;30;";

Warum kann ich in diesem Fall Einstellungen nicht füllen.
Weil du strcpy() verwenden solltest.
Title: Re: Char trennen und in int umwandeln
Post by: Rentner on Dec 30, 2019, 06:27 pm
Hallo,

hab mal in meiner Bastelkiste gewühlt , und ein Beipiel gefunden mit dem ich mal "geübt" habe verschiedene Datentypen aus einer C-Zeichenkette auszulesen. Sollte eigendlich so laufen.

Heinz

Code: [Select]

char daten[50] = "1;09:30:12;100;200;300;2.55;-1.123";

int devAdress = 0;
char zeit[20];
int iwert1, iwert2, iwert3;
float fwert1, fwert2;


void setup() {
  Serial.begin(9600);
  Serial.println(daten);
  CStringToWert(daten);


 
  Serial.print("Device Adresse\t"); Serial.println(devAdress);
  Serial.print("Zeit    \t"); Serial.println(zeit);
  Serial.print("Integer 1\t"); Serial.println(iwert1);
  Serial.print("Integer 2\t"); Serial.println(iwert2);
  Serial.print("Integer 3\t"); Serial.println(iwert3);

  Serial.print("Float 1  \t"); Serial.println(fwert1);
  Serial.print("Float 2  \t"); Serial.println(fwert2);
}

void loop() {
  // put your main code here, to run repeatedly:
}

void CStringToWert(char *instr) {
  // füllt daten aus einem C-String in Daten

  devAdress = atoi(strtok(instr, ";"));

  if (devAdress == 1) {
    strcpy(zeit, strtok(NULL, ";"));

    iwert1 = atoi(strtok(NULL, ";"));
    iwert2 = atoi(strtok(NULL, ";"));
    iwert3 = atoi(strtok(NULL, ";"));

    fwert1 = atof(strtok(NULL, ";"));
    fwert2 = atof(strtok(NULL, ";"));
  }


}

Title: Re: Char trennen und in int umwandeln
Post by: ArdunioArti on Dec 30, 2019, 07:31 pm
Vielen Dank an alle. Jetzt ist mir doch Einiges klarer geworden. Ich habe mein Problem jetzt folgendermaßen gelöst.

Code: [Select]
char Einstellungen[] = "1;5;30";
char delimiter[] = ";";
char *ptr;
int Einzelwert[3];
int ZeigerEinzelwert = 0;


void setup() {
  while (!Serial);               
  Serial.begin(9600);

}

void loop() {

ptr = strtok(Einstellungen, delimiter); // initialisieren und ersten Abschnitt erstellen
while(ptr != NULL) {

 
  Einzelwert[ZeigerEinzelwert]= atoi(ptr);

  ZeigerEinzelwert ++;

  ptr = strtok(NULL, delimiter);
 
}
  ZeigerEinzelwert = 0;
  Serial.println(Einzelwert[0]); 
  Serial.println(Einzelwert[1]);
  Serial.println(Einzelwert[2]);
delay(10000);
}
Title: Re: Char trennen und in int umwandeln
Post by: Doc_Arduino on Dec 30, 2019, 11:40 pm
Hallo,

fein.

Eins noch. Ich weiß nicht wie konstant deine Datensätze sind. Du solltest jedoch aufpassen bzw. im Hinterkopf behalten, dass dein Zielarray immer groß genug ist zur Datenaufnahme. Denn du schreibst hier schon fast unkontrolliert ins Zielarray. Dein Inkrement wird im Grunde nicht kontrolliert. Das passt "nur" für dieses Beispiel.
Code: [Select]
Einzelwert[ZeigerEinzelwert]= atoi(ptr);
ZeigerEinzelwert++;


Ansonsten wird es passieren du schreibst darüber hinaus und damit wild im RAM rum.
Einfachste Lösung wäre Zielarray gleich groß wie Datenarray zu setzen. In dem Fall 7.
Title: Re: Char trennen und in int umwandeln
Post by: Serenifly on Dec 30, 2019, 11:43 pm
Einfachste Lösung wäre Zielarray gleich groß wie Datenarray zu setzen. In dem Fall 7.
Etwas vernünftiger ist es in der while-Schleife zu überprüfen ob der Index noch gültig ist
Title: Re: Char trennen und in int umwandeln
Post by: Doc_Arduino on Dec 31, 2019, 03:31 pm
Hallo,

korrekt.