How to search word in a file from sd card?

Hi, friends
I am trying from yesterday i am not able to search a word in a file

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

File myFile;

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
 
  Serial.print("Initializing SD card...");

  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");

  
  // re-open the file for reading:
  myFile = SD.open("text1.txt");
  if (myFile) {
    Serial.println("text1.txt:");

    // read from the file until there's nothing else in it:
   while(myFile.available()) {
      Serial.write(myFile.read());
//    char val=myFile.read();
    if(myFile.read()=='second')
    {
         Serial.Write(myFile.read());

    }
    }
    // close the file:
    myFile.close();
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  }
}

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

I am not able to get the searched word help me…

Homework?

Do you know what algorithm you're supposed to use? Or does your teacher want you to discover an inefficient algorithm by yourself before teaching you the more efficient ones?

Your current pseudocode looks like you're trying to print the entire file up to the character in the file which comes after the word 'second'. Am I correct?

I believe that I an right in saying that the myFile.read() method reads one byte so

if(myFile.read()=='second')

is never going to succeed.

You need to read a whole word from the file then compare it with what you a looking for. How do you determine what constitutes a word ? Start at the beginning of the file, save each character you read until you read something that is not a character such as a space, punctuation, carriage return, linefeed or end of file, putting each character into an array of chars. When you have a whole word in the array you can compare it with your target word.

Well, that algorithm won't find the word 'seconds', which may or may not have been part of the original specification. It's certainly a workable algorithm for some purposes.

I read the original code as pseudocode. It's obvious what he wants it to do and the question is "How do I do that?"

'Stream.find()', ('myFile.find()'),might be one way of doing it. (I've never used it, so can't say for sure.)
It only returns 'true' or 'false', not a pointer, but hopefully it would leave the file pointer in the correct position, or at worst, at the end of the string.
I don't have an SD card module hooked up right now, or I'd give it a spin.

I had a play with the 'find()' function today. It leaves the file pointer at the first character after the search string.
Then the file pointer's position can be retrieved using 'position()' and moved using 'seek()' based on that position if necessary.
For a test, I found the string "onto", then backed up the file pointer and replaced it with "ONTO". Nice and easy.

One point - if the file is opened for reading and writing with the "FILE_WRITE" parameter, the file pointer is automatically positioned at the end of the file, so needs to be moved back to the beginning of the file with "myFile.seek(0);" before 'find()' will be successful. (Not needed if the file is opened for reading only.)

UKHeliBob:
I believe that I an right in saying that the myFile.read() method reads one byte so

if(myFile.read()=='second')

is never going to succeed.

For more reasons than one.

It should be comparing to "second" not 'second'.

That is apart from the issue that read() returns one byte, not lots of them.

Please use CTRL-T in the IDE before copying code to post.
It autoindents your code and makes it more readable.

+1 for UKHeliBob (post#2) method to learn the most.

robtillaart:
+1 for UKHeliBob (post#2) method to learn the most.

That's very true, and I agree, but most people that post questions here are more interested in "easy" than learning properly.

most people that post questions here are more interested in “easy” than learning properly.

Until I have seen at least a few posts from someone I find it difficult to know what category to put them in and hence how to frame my replies.

UKHeliBob:
Until I have seen at least a few posts from someone I find it difficult to know what category to put them in and hence how to frame my replies.

I know what you mean, Bob. A lot of people do want to learn the language thoroughly, it's just sorting them from the "easy" people.

Not that long ago, everyone started with the basics of binary, hex etc, then onto "Hello World" etc, before progressing on to the more complex stuff, but not any more. It's getting almost too easy with Arduino and the various shields/libraries.
I think I'm showing my age again. :smiley:

And I'm still glad I took the time to learn about 'Stream.Find()'. Another useful tool in my belt.

Hello Everyone,

Is there a SD library with search functions?

The file that I need to search in is as large as 18Mb (max)

Thank you in advance

Ronen

That is a very large file for an Arduino. It would likely take many minutes to read the file and you can only keep a tiny tiny fraction of the file in memory at one time.

What will you do when you find the word? It it just a simple yes/no "word was (not) found" output? Then it would be better to put the SD card in your laptop and search there.

The Arduino logs the system information every minute, so it's 1440 lines per 24 hour time about 6 months. You get the idea.

Reading it locally is not a problem, I upload the log file to a server app and the server creates all kinds of statistics, etc. out of the log file.

Now, remotely I will be crazy to upload this through a Bluetooth connection and then through a socket connection to access the complete file where I only need 1440 lines of it.

If there was a library for searching for a specific date, for example, I could download 1440 line only.

I could also write the log of each day in a separate file 15122017.log 16122017.log etc...

Thank you

Ronen

What system? We can't see what's in front of you.

Yes, that makes sense - read down to a specific date, then output the data starting from that point. How do you determine when to stop?

I would make a different file for each day. Then I can just download an individual file without having to search for it.

Some options
1)
If the records are fixed length, you can seek the number of minutes since start times the record length.
2)
Use an index file if the records are not the same length; every time you write data to the first file, you also write the position in the index file. Further as above; hence the best is to have this file fixed width.