Need advice on how to store data from a file to an array using SdFat [SOLVED]

Dear experts,

I ame using the SdFat lib on a arduino duemilanove + ethernetshield to read some data from a file to a char array.

problem: When i print out the char array via serial.print… the char array is empty…

ex. here i load and store the data from the file to my stuct array…when i print out here then it works…however:

while ((n = rdfile.fgets(line, sizeof(line))) > 0) {
if(i<10)temp*.packetBuffer = line;*
Serial.println( temp_.packetBuffer ); // here there is data_
* i++;*
* }*
… if i print out after the while then there is no data in my temp struct (i belive this may be caused by the pointer…if this is the case can anyone give me some hint to a workaround?):
for(int j =0; j<10; j++)
{
* Serial.print( "Data " );*
* Serial.print( j );*
* Serial.print( ": " );*

_ Serial.println( temp[j].packetBuffer ); // here there is no data_
}
can anyone help me out or even give me some hint on some better way if possible?
I am using the demo code followed with the Sdfat lib… I will appriziate any help i can get…thanks in advance
```
*// Demo of fgets function to read lines from a file.
#include <SdFat.h>
SdFat sd;
// print stream
ArduinoOutStream cout(Serial);

typedef struct tprofiles
{
 char *packetBuffer;

}tprofiles;

tprofiles temp[10]; // struct array to hold the data i read out from the file

//------------------------------------------------------------------------------
// store error strings in flash memory
#define error(s) sd.errorHalt_P(PSTR(s))
//------------------------------------------------------------------------------
void demoFgets() {
 char line[250];
 int n,i=0;
 // open test file
 SdFile rdfile(“FGETS.TXT”, O_READ);
 
 // check for open error
 if (!rdfile.isOpen()) error(“demoFgets”);
 
 cout << endl << pstr(
   “Lines with ‘>’ end with a ‘\n’ character\n”
   “Lines with ‘#’ do not end with a ‘\n’ character\n”
   “\n”);
   
 // read lines from the file
 while ((n = rdfile.fgets(line, sizeof(line))) > 0) {
   if(i<10)temp[i].packetBuffer = line;
   Serial.println( temp[i].packetBuffer );  // here there is data
   i++;
 }
 
  for(int j =0; j<10; j++)
 {
   Serial.print( “Data " );
   Serial.print( j );
   Serial.print( “: " );
   
   Serial.println( temp[j].packetBuffer ); // here there is no data
 }
 
}
//------------------------------------------------------------------------------
void makeTestFile() {
 // create or open test file
 SdFile wrfile(“FGETS.TXT”, O_WRITE | O_CREAT | O_TRUNC);
 
 // check for open error
 if (!wrfile.isOpen()) error(“MakeTestFile”);
 
 // write test file
 wrfile.write_P(PSTR(
   “name#1#2#3#4#5#6#7#8#9#10#11#12#13#14#15#16#17#18#19#20#21#22#23#24#25#26#27#28#29#30#31#32#33#34#35#36#37#38#39#40#41#42#43#44#45#46#47#48#49#50#51#52#53#54#55#56#57#58#59#60#61#62#63#64 \n”
   “name1#1#2#3#4#5#6#7#8#9#10#11#12#13#14#15#16#17#18#19#20#21#22#23#24#25#26#27#28#29#30#31#32#33#34#35#36#37#38#39#40#41#42#43#44#45#46#47#48#49#50#51#52#53#54#55#56#57#58#59#60#61#62#63#64 \n”
 ));
 // wrfile is closed when it goes out of scope
}
//------------------------------------------------------------------------------
void setup(void) {
 Serial.begin(9600);
 cout << pstr(“Type any character to start\n”);
 while (!Serial.available());
 
 // initialize the file system
 if (!sd.init(SPI_HALF_SPEED, 4)) sd.initErrorHalt();
 
 makeTestFile();
 
 demoFgets();
 
 cout << pstr(”\nDone\n”);
}
void loop(void) {}
_
```*_

  while ((n = rdfile.fgets(line, sizeof(line))) > 0) {
    if(i<10)temp[i].packetBuffer = line;
    Serial.println( temp[i].packetBuffer );  // [b]here there is data[/b]
    i++;
  }

This makes temp[ i ].packetBuffer point to line (not a copy of line).

Apparently, there are less than 10 lines in your file, so line is empty when rdfile.fgets() gets to the end of file.

Then, you print out the data pointer to be all 10 pointers, some of which are NULL and the rest of which point to the same place.

You need to change

    if(i<10)temp[i].packetBuffer = line;

to

    if(i<10)temp[i].packetBuffer = strdup(line);

to make packetBuffer point to a copy of the data.

Each packetBuffer pointer will then point to a different location.

thanks that helps a lot :slight_smile:

/cheers