INFO: Dieses Forum nutzt Cookies...
Cookies sind für den Betrieb des Forums unverzichtbar. Mit der Nutzung des Forums erklärst Du dich damit einverstanden, dass wir Cookies verwenden.

Es wird in jedem Fall ein Cookie gesetzt um diesen Hinweis nicht mehr zu erhalten. Desweiteren setzen wir Google Adsense und Google Analytics ein.

Antwort schreiben 
 
Themabewertung:
  • 0 Bewertungen - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
File-Lese-Funktion mir Rückgabe wert ANSI C string: wie?
22.02.2015, 14:08 (Dieser Beitrag wurde zuletzt bearbeitet: 23.02.2015 09:31 von HaWe.)
Beitrag #9
RE: File-Lese-Funktion mir Rückgabe wert ANSI C string: wie?
juhuu, jetzt klappt komplett den String wieder neu lesen aus der Datei inkl rück-konvertieren zur Zahl! (Indices sind schon manchmal schwer... Undecided )

Das mit der Zuweisung
sdata = fgets( )
hat leider nicht funktioniert wegen unverträglichen Datentypen (char * mit char[128] (???) )
- macht aber nichts!
(wenn man das allerdings doch noch hinkriegte, hätte man sogar eine "echte" fgets() funktion wie ANSI C Wink


Jetzt aber klappt es jedenfalls! 8-)

Code:
/*
  SD card read/write

This example code is in the public domain.

*/

#include <SPI.h>
#include <SD.h>

#define SD_CSpin 4

File myFile;
char fname[64];

char sbuf[64];
char sdata[128];
char cln[]="                    ";





char * fgets ( char * str, uint32_t num, File * stream ) {
  uint32_t i;
  
  i=0;
  strcpy(str, "");
  while ( stream->available() && (i<num)  ) {    
     str[i]=stream->read() ;
     if(str[i] == '\n')   {      // end of string: CR
         str[i] = '\0';          // CR mit Null-Terminierung überschreiben
         goto ok;
     }
     ++i;        
  }  
  ok:
  return(str);
}

  



void setup()
{
  pinMode(SD_CSpin, OUTPUT);  
  
  Serial.begin(9600);
  
  sprintf(sbuf,"#: SD Initializing...");
  Serial.println(sbuf);
  // CS is pin 4. It's set as an output by default.


  while(!SD.begin(SD_CSpin) ) {
    sprintf(sbuf,"#: ...SD init failed");
    Serial.println(sbuf);
    delay(1000);
  }
  
  sprintf(sbuf,"#: ...SD OK !          ");
  Serial.println(sbuf);

  sprintf(fname,"test.txt");
  
  if (SD.exists(fname) ) {
    sprintf(sbuf,"#: %s exists     ",fname);
    Serial.println(sbuf);
    sprintf(sbuf,"#: Removing %s      ",fname);
    Serial.println(sbuf);
    SD.remove("test.txt");
    // removed: success ?
    if (SD.exists(fname) ) {
       sprintf(sbuf,"#: %s  exists     ",fname);
       Serial.println(sbuf);  
    }
    else {
       sprintf(sbuf,"#: %s  N/A     ",fname);
       Serial.println(sbuf);
     }
  }
  
  
  
  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  int16_t  p, i, cnt=0;
  float    x;
  
  myFile = SD.open(fname, FILE_WRITE);
  
  if (myFile) {
    // if the file opened okay, write to it, then close file:
    sprintf(sbuf,"#: Writing string to %s ",fname);
    Serial.println(sbuf);
    
    // write data to file
    sprintf(sdata, "%d",1);
    myFile.println(sdata);
    Serial.println(sdata);
    sprintf(sdata, "%d", 2);
    myFile.println(sdata);
    Serial.println(sdata);
    sprintf(sdata, "%f", PI);
    myFile.println(sdata);
    Serial.println(sdata);
    sprintf(sdata, "%f", 987.654);
    myFile.println(sdata);
    Serial.println(sdata);
        
    
    // close the file:
    myFile.close();
    sprintf(sbuf,"#: %s closed.   \n",fname);
    Serial.println(sbuf);
  }  
  else {
    // if the file didn't open, print an error:
    sprintf(sbuf,"#: error opening %s   ",fname);
    Serial.println(sbuf);
  }
  

  // re-open the file for reading:
  myFile = SD.open(fname);
  if (myFile) {
    sprintf(sbuf,"#: reading %s ",fname);
    Serial.println(sbuf);

    // read from the file until there's nothing else in it:
    i=0;
    cnt=1;  
    
    while (myFile.available()) {
      strcpy(sdata, "");
      fgets ( sdata, 20, &myFile );
       if (sdata!="") Serial.print(sdata); Serial.println("          //  as string");
       if (cnt<3) {
          p=atoi(sdata);
          Serial.print(p); Serial.println("          //  as integer");
       }
       else  {
          x=atof(sdata);
          Serial.print(x); Serial.println("          //  as float");
       }
       ++cnt;
    }  
    // close the file:
    myFile.close();        
    sprintf(sbuf,"#: %s closed.   \n",fname);
    Serial.println(sbuf);
  } else {
    // if the file didn't open, print an error:
    sprintf(sbuf,"#: error opening %s   ",fname);
    Serial.println(sbuf);

  }
}

void loop()
{
  // nothing happens after setup
}

Ausgabe:
Code:
#: SD Initializing...
#: ...SD init failed
#: ...SD init failed
#: ...SD OK !          
#: test.txt exists    
#: Removing test.txt      
#: test.txt  N/A    
#: Writing string to test.txt
1
2
3.141593
987.654000
#: test.txt closed.  

#: reading test.txt
1          //  as string
1          //  as integer
2          //  as string
2          //  as integer
3.141593          //  as string
3.14          //  as float
987.654000          //  as string
987.65          //  as float
#: test.txt closed.


besten Dank, Thorsten ! Big Grin
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
23.02.2015, 09:28 (Dieser Beitrag wurde zuletzt bearbeitet: 23.02.2015 09:31 von HaWe.)
Beitrag #10
RE: File-Lese-Funktion mir Rückgabe wert ANSI C string: wie?
jetzt würde mich nur noch aus Neugier interessieren:

wie weist man den Rückgabewert dieser Funktion korrekt einem char-Arrays (String) zu?

Code:
char * fgets ( char * str, uint32_t num, File * stream ) {
  uint32_t i;
  
  i=0;
  strcpy(str, "");
  while ( stream->available() && (i<num)  ) {    
     str[i]=stream->read() ;
     if(str[i] == '\n')   {      // end of string: CR
         str[i] = '\0';          // CR mit Null-Terminierung überschreiben
         goto ok;
     }
     ++i;        
  }  
  ok:
  return(str);
}


Das hier:

char sbuf[128];
sbuf= fgets ( sbuf, 20, &myFile)

will er nicht so recht....
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
23.02.2015, 09:46
Beitrag #11
RE: File-Lese-Funktion mir Rückgabe wert ANSI C string: wie?
Hi,
ich will jetzt nicht nochmal die Diskussion starten, ob das nun sinnvoll ist oder nicht. Damit können wir dann bei den ersten Memory leaks und Speicherüberschreibern anfangen.
Ich dachte eigentlich, dass das im Prinzip geht. Ich habe es jetzt selbst mal ausprobiert. Anscheinend ist der Compiler doch schlauer, als ich dachte. So geht's:
Code:
char sbuf[128];
char* result;
result = fgets ( sbuf, 20, &myFile);
Das ist meiner Meinung nach sehr sinnvoll, weil das andere den Speicherbereich von sbuf unter Umständen unerreichbar machen würde.
Vielleicht hast Du da ein Missverständnis: Arrays sind in C(++) keine L-Values. D.h. man kann einem Array nicht wirklich etwas zuweisen und man kann auch kein Array als Rückgabewert einer Funktion verwenden. Überall wo es so aussieht, als ob es ein L-Value wäre (z.B. bei der Parameterübergabe an eine Funktion), wird tatsächlich nur ein Zeiger auf den Anfang des Speicherbereichs übergeben. Deshalb kann man auch einer Funktion die als "void foo(char*)" deklariert ist, ein char-Array übergeben.
Gruß,
Thorsten

Falls ich mit einer Antwort helfen konnte, wuerde ich mich freuen, ein paar Fotos oder auch ein kleines Filmchen des zugehoerigen Projekts zu sehen.
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
23.02.2015, 10:45 (Dieser Beitrag wurde zuletzt bearbeitet: 23.02.2015 10:48 von HaWe.)
Beitrag #12
RE: File-Lese-Funktion mir Rückgabe wert ANSI C string: wie?
ahaa, danke!
ich will es jetzt auch gar nicht problematisieren, es geht ja auch ohne den Rückgabewert, ich möchte es nur gern verstehen.
Und außerdem wollte ich die AANSI C Funktion so gut wie es geht kopieren, damit der Code halbwegs kompatibel zu stdio.h ist

Was fängt man denn jetzt z.B. mit dem Rückgabewert, der ja wohl ein Pointer auf das erste Element des Arrays ist, an?

in der fgets-Funktion steht ja
return(str);

1) wird dann wirklich str übergeben? Oder der Wert (die Speicher-Nummer) des Pointers da drauf ?
2) wie arbeitet man mit dem Rückgabewert char* result weiter?
Ich will jetzt nichts riskieren, aber ginge dann so etwas wie
sbuf=result
oder
sbuf=&result?

(du merkst, Pointer sind nicht gerade wie meine Westentasche)
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
23.02.2015, 10:55
Beitrag #13
RE: File-Lese-Funktion mir Rückgabe wert ANSI C string: wie?
(23.02.2015 10:45)HaWe schrieb:  Was fängt man denn jetzt z.B. mit dem Rückgabewert, der ja wohl ein Pointer auf das erste Element des Arrays ist, an?
Tja, das ist ja mein Punkt. Nicht viel. Im Prinzip kannst Du damit alles machen, was Du auch mit einem char[] machen kannst.

Zitat:in der fgets-Funktion steht ja
return(str);
1) wird dann wirklich str übergeben? Oder der Wert (die Speicher-Nummer) des Pointers da drauf ?
Es wird str übergeben. str ist aber der Zeiger, also die Speicher-Nummer. Man kann den "Wert" eines Arrays nicht übergeben! Das habe ich doch versucht, oben zu erklären.

Zitat:2) wie arbeitet man mit dem Rückgabewert char* result weiter?
Ich will jetzt nichts riskieren, aber ginge dann so etwas wie
sbuf=result
oder
sbuf=&result?
Nein, beides ist quatsch, da sbuf kein L-Value ist. D.h. man kann es nicht "Links vom =" verwenden. Was sollte es auch bedeuten?

Gruß,
Thorsten

Falls ich mit einer Antwort helfen konnte, wuerde ich mich freuen, ein paar Fotos oder auch ein kleines Filmchen des zugehoerigen Projekts zu sehen.
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
23.02.2015, 11:09
Beitrag #14
RE: File-Lese-Funktion mir Rückgabe wert ANSI C string: wie?
achso, langsam lichtet sich das Dunkel...

bei
char sbuf[]
kann ich ja auf sbuf[i] zugreifen (zum lesen/schreiben), z.B
sbuf[n]='\0';

- kann ich bei
char *result
auch auch auf ein result[i] in gleicher Weise zugreifen? also
result[n]='\0';
?
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
23.02.2015, 11:21 (Dieser Beitrag wurde zuletzt bearbeitet: 23.02.2015 11:23 von Thorsten Pferdekämper.)
Beitrag #15
RE: File-Lese-Funktion mir Rückgabe wert ANSI C string: wie?
Hi,
ja, sbuf[n] ist ein L-Value. Da kann man reinschreiben. Im Prinzip ist sbuf[n] ein Synonym für sowas wie:
Code:
*(sbuf + n)
D.h. für char ist es die n-te Speicherstelle nach sbuf.
Das geht auch für "normale" Pointer. Statt
Code:
*(result + n)
Kann man auch kurz "result[n]" schreiben.
In allen Fällen muss man aufpassen, dass man nicht über die Array-Grenzen rausgeht und man nicht versucht ungültige Zeiger zu verwenden. Wenn man einen Zeiger hat, dann muss man irgendwie sicherstellen, dass er auch auf einen sinnvollen Speicherbereich zeigt.
Gruß,
Thorsten

Falls ich mit einer Antwort helfen konnte, wuerde ich mich freuen, ein paar Fotos oder auch ein kleines Filmchen des zugehoerigen Projekts zu sehen.
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
23.02.2015, 11:38 (Dieser Beitrag wurde zuletzt bearbeitet: 23.02.2015 11:38 von HaWe.)
Beitrag #16
RE: File-Lese-Funktion mir Rückgabe wert ANSI C string: wie?
das ist wirklich gut! Cool
Jetzt kann ich nämlich fgets direkt als Argument in eine andere Funktion hineinschreiben, die quasi den Rückgabewert als "string"-Argument weiterverwenden kann, z.B. um Zeichen zu finden oder ihn in direkt in Zahlen umzuwandeln.

Das hat mir sehr geholfen, herzlichen Dank! Smile
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
Antwort schreiben 


Möglicherweise verwandte Themen...
Thema: Verfasser Antworten: Ansichten: Letzter Beitrag
  String / HTTP Request Marc2014 2 68 08.12.2016 09:05
Letzter Beitrag: amithlon
  No such file Brother Tak 3 106 21.11.2016 10:24
Letzter Beitrag: Brother Tak
  String zusammensetzen Mathias 13 554 01.09.2016 21:15
Letzter Beitrag: Mathias
  String-Array füllen? torsten_156 9 452 08.07.2016 20:07
Letzter Beitrag: amithlon
  String in EEPROM Speichern BennIY 2 417 27.06.2016 10:23
Letzter Beitrag: BennIY
  Funktion mit Parameterübergabe - u8g torsten_156 8 403 22.06.2016 18:53
Letzter Beitrag: Pit
  String - Buchstabenposition auswerten scritch 5 666 01.04.2016 16:25
Letzter Beitrag: rkuehle
  Funktion in Loop einmalig ausführen Haustechno 4 646 09.03.2016 22:43
Letzter Beitrag: Haustechno
  String nach UTF16 konvertieren (UTF-16) ThoEngel 0 301 20.02.2016 19:22
Letzter Beitrag: ThoEngel
  HC-05 Modul auf Funktion prüfen. arduinofan 2 365 03.02.2016 19:18
Letzter Beitrag: arduinofan

Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste