Go Down

Topic: Char trennen und in int umwandeln (Read 229 times) previous topic - next topic

ArdunioArti

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.

Serenifly

#1
Dec 30, 2019, 05:12 pm Last Edit: Dec 30, 2019, 05:13 pm by Serenifly
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

combie

#2
Dec 30, 2019, 05:17 pm Last Edit: Dec 30, 2019, 05:17 pm by combie
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.


Es ist offensichtlich, dass uns die Umstände alleine nicht glücklich oder unglücklich machen.
Es ist die Art unserer Reaktion darauf, die unsere Gefühle bestimmt.

Rentner


ArdunioArti

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 steht, dass ein String auch nur ein Array des Datentyps char ist.

Und was ist dann ein C String ?


combie

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'
Es ist offensichtlich, dass uns die Umstände alleine nicht glücklich oder unglücklich machen.
Es ist die Art unserer Reaktion darauf, die unsere Gefühle bestimmt.

ArdunioArti

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.



Tommy56

#7
Dec 30, 2019, 06:05 pm Last Edit: Dec 30, 2019, 06:13 pm by Tommy56
Einstellungen ={1,5, 30} ; als Charwerte

Gruß Tommy
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

Serenifly

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

combie

#9
Dec 30, 2019, 06:13 pm Last Edit: Dec 30, 2019, 06:17 pm by combie
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.
Es ist offensichtlich, dass uns die Umstände alleine nicht glücklich oder unglücklich machen.
Es ist die Art unserer Reaktion darauf, die unsere Gefühle bestimmt.

Rentner

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, ";"));
  }


}


ArdunioArti

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);
}

Doc_Arduino

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.
Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

Serenifly

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

Doc_Arduino

Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

Go Up