Text-Datei von SD Karte Zeile für Zeile auslesen...

Hallo zusammen,

Ich schaffes einfach nicht die eine Text-Datei auf der SD Karte richtig auszulesen...

Text-Datei (jede Zeile eine Information):
Mustermann
65
Nord-West-Straße

Nun möchte ich jede Zeile auslesen und in einer Variable zur Verfügung haben.

Hier mein Code, der mich zur Verzweiflung treibt.

Hat einer von Euch das Problem schon mal in den Griff bekommen?
Wenn ja, jede Hilfe ist herzlich Willkommen!

#include <SD.h>

File myFile;

void setup()
{

  Serial.begin(9600);

   pinMode(10, OUTPUT);
   
  if (!SD.begin(4)) {
    return;
  }
  
  char MyChar;
  myFile = SD.open("test.txt");
  if (myFile) {
    char Name[30];
    char Alter[5];
    int Zeile = 1;
    int Zeichen = 1;
    while (myFile.available()) {
      MyChar = myFile.read();
       if ((MyChar=='\n') || (MyChar=='\r')) {
        Zeile++;
        Zeichen = 1;
       }else{
          switch (Zeile) {
            case 1:
               if ((MyChar!=':') || (MyChar!=' ')){
                Name[Zeichen] = MyChar;
               }
              break;
            case 2:
                if ((MyChar!=':') || (MyChar!=' ')){
                Alter[Zeichen] = myFile.read();
               }           
              break;            
            case 3:
              break;  
            case 4:
              break;  
            default:
              break;
          }
     Zeichen++;
       }
    }
     Serial.println(Name);
     Serial.print(" Alter: ");
     Serial.println(Alter);
    // close the file:
    myFile.close();
  } else {
    Serial.println("error opening test.txt");
  }
  
}

void loop()
{

}

Gruß, Matze

Bevor du verzweifelst, füg lieber mehr Serial Testausgaben ein.
Wenn z.B. keine Karte drin ist, oder der Kartenadapter falsch angeschlossen ist, zeigt dein sketch dir gar nichts an.

Übrigens, was siehst du im SerialMonitor ?

Dann hängt es davon ab, was anfangs in Name[0] drin steht. Wenn das eine 0 ist, siehst du auch nicht viel:
Fang mit

[b]int Zeichen=0; 
[/b]

an...

Das sehe ich im SerialMonitor:

ØNameMuster 2, 3.ïՏ1¾=ïs«·]ÿÒ
Alter: ÿ¹?~ý9

Interessanterweise habe ich gerade festgestellt, dass die "2, 3." vorher in der Datei stand.
Ich habe das ReadWrite Beispiel vorher laufen lassen...

Wann da jemand Licht ins Dunke bringen würde...

Matze

Hallo zusammen,

ich habe gerade noch ein bissl weiter rumprobiert und bin auf folgendes gestoßen.

Die Text-Datei enthält folgendes:
NameMuster
irgendwas
irgendwas
irgendwas
us.w.

Hier der Code

#include <SD.h>

File myFile;

void setup()
{

  Serial.begin(9600);

   pinMode(10, OUTPUT);
   
  if (!SD.begin(4)) {
    return;
  }
  
  char MyChar;
  myFile = SD.open("test.txt");
  if (myFile) {
    char Name[30];
    char Alter[5];
    int Zeile = 1;
    int Zeichen = 1;
    while (myFile.available()) {
      MyChar = myFile.read();
       if ((MyChar=='\n') || (MyChar=='\r')) {
        Zeile++;
        Zeichen = 1;
       }else{
          switch (Zeile) {
            case 1:
               if ((MyChar!=':') || (MyChar!=' ')){
                Name[Zeichen] = MyChar;
                Serial.print(Name[Zeichen]);
               }
              break;
            case 2:
               }           
              break;            
            case 3:
              break;  
            case 4:
              break;  
            default:
              break;
          }
     Zeichen++;
       }
    }
     Serial.println();
     for (int i=0; i<30; i++) {
       Serial.print(Name[i]);
     }

    myFile.close();
  } else {
    Serial.println("error opening test.txt");
  }
  
}

void loop()
{

}

Serial Monitor gib das aus
NameMuster
TNameMusterè ïՏ1test.txtP

Und das kann ich mir nicht erklären. Das selbe char array verändert sich...

:~

Bin für jede Hilfe dankbar...

Matze

Ich verwende die sdFat Lib und die fgets() Methode der sdFile Klasse

Die liest automatisch bis zum Zeilen-Ende (oder optional bis zu einem Delimiter) und entfernt ein eventuelles CR. Das LF bleibt

Get a string from a file.

fgets() reads bytes from a file into the array pointed to by str, until num - 1 bytes are read, or a delimiter is read and transferred to str, or end-of-file is encountered. The string is then terminated with a null byte.

fgets() deletes CR, '\r', from the string. This insures only a '\n' terminates the string for Windows text files which use CRLF for newline.

Parameters:
[out] str Pointer to the array where the string is stored.
[in] num Maximum number of characters to be read (including the final null byte). Usually the length of the array str is used.
[in] delim Optional set of delimiters. The default is "\n".

Returns:
For success fgets() returns the length of the string in str. If no data is read, fgets() returns zero for EOF or -1 if an error occurred.

http://code.google.com/p/sdfatlib/

Besser ist da man liest erst mal eine Zeile ganz ein und splittet diese dann in ihre Bestandteile. Die Länge von Teil-Strings bis zu einem Trennzeichen kann man z.B. mit strcspn() bestimmen. Dann kann man strncpy() verwenden um den Teil-String zu kopieren. strtok() ist manchmal auch eine gute Option, vor allem wenn man viele durch Kommas getrennte Teil hat. Das liefert immer einen Pointer auf das nächste Token und ersetzt den Delimiter durch NULL, wodurch die Tei-Strings gleich terminiert sind.
Zahlen kann man mit atoi() oder strtol() in Integer wandeln.

Kommt aber darauf an was man mit den Daten genau machen will. Manche Varianten sind auch Overkill für einfache Fälle

michael_x:
Fang mit

[b]int Zeichen=0; 

[/b]


an...

Hi Matze,

ich hab mal ein 'Beispiel' gebastelt -
das geht ein bisschen weiter als das was du hier gefragt hast...

es 'analysiert' (parst) jede Zeile anhand des ersten Zeichens.
das Format sieht dann etwa so aus:

key:value

wobei bei key nur das erste Zeichend entscheidend ist - der value wird ab dem ':' ausgewertet-
bedeutet man kann nach dem ersten entscheidenden zeichen noch mehr zeichen benutzen um ein key zu beschreiben.
des weiteren wird jede Zeile die mit einer '#' startet als Kommentar ignoriert.

in dem Zip sind drei Test Dateien mit drin:
test1.txt Windows Zeilenenden
test2.txt Linux Zeilenenden
test3.txt Mac(alt) Zeilenenden

jede Zeile wird beim einlesen auf die länge geprüft -
wenn sie länger ist als der Interne Buffer wird der rest der Zeile ignoriert.
das erlaubt auch sehr lange kommentare.

das script hat auch ein Serielles Menu eingebaut -
die Baudrate vom Seriellen Monitor muss auf 115200 gestellt werden.

mit 'r' wird die Karte angesprochen und die drei Dateien nach einander eingelesen.

was man noch ergänzen könnte:

  • Einlesen welche Dateien sich auf der Karte befinden
  • Karten-Informationen auslesen

viel spaß damit - und wenn noch fragen - gerne fragen :wink:

sonnige grüße
stefan

test__SDCard_ParseFile__20140219_0910.zip (8.22 KB)

test__SDCard_ParseFile.ino (26.1 KB)