Go Down

Topic: [SOLVED] Can't open file from dynamic filepath (Read 110 times) previous topic - next topic

AloyseTech

May 17, 2016, 05:58 pm Last Edit: May 17, 2016, 06:48 pm by AloyseTech
Hi,

I've been struggling with an issue for a week now. I'm trying to read a filepath from a text file, and the open the said file.
The following code doesn't work :

Code: [Select]

SdFile prev,file;
char nextApp[30];

if (prev.open("/System/bin/NEXTAPP.TXT", O_READ))
  {
    char c = 0;
    int i = 0;
    String s = "";

    memset(nextApp, 0, 30);

    while (c != '\n')
    {
      c = prev.read();
      if (c != '\n')
      {
        s += char(c);
        nextApp[i] = c;
      }
      i++;
    }

    SerialUSB.println(strcmp(s.c_str(),"/test/test.bin")?"Match":"Differ"); // Displays "Match"
    SerialUSB.println(strcmp(nextApp,"/test/test.bin")?"Match":"Differ"); // Displays "Match" as well

    if (file.open(nextApp, O_READ))
    {
      SerialUSB.println("Success open from char *");
    }
    else if (file.open(s.c_str(), O_READ))
    {
      SerialUSB.println("Success open from string c_str");
    }
}


But this code does work :

Code: [Select]
SdFile prev,file;
char nextApp[30];

if (file.open("/test/test.bin", O_READ))
{
  SerialUSB.println("Success open");
}


I would really appreciate any help... :)
Info :
- I'm using a custom Arduino Zero board.
- The NEXTAPP.TXT file contains "/test/test.bin\n"

el_supremo

strcmp returns zero on an exact match and non-zero otherwise.
Code: [Select]
SerialUSB.println(strcmp(s.c_str(),"/test/test.bin")?"Match":"Differ");
This will print "Match" when the condition is non-zero and therefore when the strings do not match.
Exchange the "Match" and "Differ" strings.

Pete

el_supremo

BTW. You should put i++ inside the if statement so that it doesn't count the '\n'. That way "i" will be the length of the string when the '\n' is found and the while loop exits.

Pete

AloyseTech

Thanks for your help, huge mistake with the returned value from strcmp !

Here is the full code :

Code: [Select]
#include <SdFat.h>

SdFat sd;
SdFile prev, file;

char nextApp[30] = {0};
void setup() {
  // put your setup code here, to run once:
  sd.begin(SD_CS_PIN, SPI_FULL_SPEED);

  while (!SerialUSB);

  if (prev.open("/System/Loader/NEXTAPP.TXT", O_READ))
  {
    char c = 0;
    int i = 0;
    String s = "";
    digitalWrite(13, HIGH);
    memset(nextApp, 0, 30);

    while (c != '\n')
    {
      c = prev.read();
      if (c != '\n')
      {
        s += char(c);
        nextApp[i] = c;
        i++;
      }
    }
    prev.close();


    SerialUSB.println(strcmp(s.c_str(), "/Test/Test.bin") ? "\"/Test/Test.bin\" differs from \"" + String(s.c_str()) + "\"" : "Match");
    SerialUSB.println(strcmp(nextApp, "/Test/Test.bin") ? "Differ" : "Match");

    SerialUSB.print("i = ");
    SerialUSB.println(i);
    SerialUSB.print("s.length() = ");
    SerialUSB.println(s.length());

    if (file.open(nextApp, O_READ))
    {
      SerialUSB.println("File open success using char *");
    }
    else if (file.open(s.c_str(), O_READ))
    {
      SerialUSB.println("File open success using c_str()");
    }
  }
}

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

}



Which displays this on the Serial port :

"/Test/Test.bin" differs from "/Test/Test.bin"
Differ
i = 19
s.length() = 19


AloyseTech

Oh my god I just figured out : the println function of SdFat add a CRLF, not just a LF at the end of the String... (\r\n). The Arduino Serial port is not displaying the CR, that why when I displayed both Strings, they seemed to be the same.
Issue solved :)

el_supremo

I was about to post some code which would show you exactly what was in the string. I suspected a CR or other stray characters.
There's still one thing to clear up. When you print the value of "i", that is not the same "i" as is used to index nextApp when you read the string. That "i" is declared local to the if statement and disappears once the if statement has been executed. You must have declared another "i' further back in the code, probably globally.
That is why it prints 19 instead of 14 (or 15).

Pete

el_supremo

P.S. If a text file on an SD card is created with Windows, it will also have CRLF on the end of the line. When reading text files, it is best to assume that there will be a CR as well as LF at the end of a line and add code to test for CR and ignore it if it is found.

Pete

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy