Txt data search on Arduino SD card

hi everyone...

I tried to do a data search on the data.txt file on the Arduino SD card...
but it can only be read if the data is in the first row (top), the second data and so on cannot be found...

I wonder why?
here is the code that I use
Thank You

 /*
  SD card read/write
 
 This example shows how to read and write data to and from an SD card file 	
 The circuit:
 * SD card attached to SPI bus as follows:
 ** MOSI - pin 11
 ** MISO - pin 12
 ** CLK - pin 13
 ** CS - pin 4
 
 created   Nov 2010
 by David A. Mellis
 modified 9 Apr 2012
 by Tom Igoe
 
 This example code is in the public domain.
 	 
 */
 
#include <SD.h>

const int chipSelect = 4;
File myFile;
char buf[8];

void setup()
{
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }


  Serial.print("Initializing SD card...");
  // On the Ethernet Shield, CS is pin 4. It's set as an output by default.
  // Note that even if it's not used as the CS pin, the hardware SS pin 
  // (10 on most Arduino boards, 53 on the Mega) must be left as an output 
  // or the SD library functions will not work. 
   //pinMode(10, OUTPUT);
   
  if (!SD.begin(chipSelect)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");  
    
  // re-open the file for reading:
  myFile = SD.open("data.txt");
  if (myFile) {
    Serial.println("data.txt:");
    
    // read from the file until there's nothing else in it:
    
    while (myFile.available()) {
        myFile.read(buf,8);        
        if(strncmp(buf,"18429874",8)==0)
        {
            Serial.println("Match!");       
        }
    }
    // 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 moved your topic to an appropriate forum category @ranggajulizar .

In the future, please take some time to pick the forum category that best suits the subject of your topic. There is an "About the _____ category" topic at the top of each category that explains its purpose.

This is an important part of responsible forum usage, as explained in the "How to get the best out of this forum" guide. The guide contains a lot of other useful information. Please read it.

Thanks in advance for your cooperation.

Sorry, this is my first time using this forum..
and thank you for fixing it

1 Like

How the data in the file is organized? Is it a lines with exact 8 characters each? Does that lines terminated by CR or LF?

hi b707
thank you for responding..
yes, lines are written with 8 characters..
the following data is written in the file..

without CR and LF

18429874
18429875
18429876
18429877
18429878
18429879
18429880
18429881
18429882
18429883
18429884
18429885
18429886
18429887

Sorry because I'm a beginner when it comes to Arduino storage

Are you sure?
Without line terminated, your data should looks like this:

How the data did written in the file? Or could you show the file, listed in HEX view mode ?

with CR without LF ..
like this

or if you have a string search code in the txt file... that I can use, I would be very grateful

In that case your lines has 9 chars length rather than 8, so you need to read it accordingly.
Do not forget to increase a length of buf array.

then to be able to read the next line too, is there a way?

because if I look for the second or third data it can't be found

You just need to change two lines

and

may be a function like this would work. (typed here, totally untested)

assuming you have

#include <SdFat.h>

SdFat sd;
File file;

...
// in setup
    if (!sd.begin()) return false; // Initialization failed

then the function could be

bool findStringInFile(const char *filename, const char *searchString, size_t &pos) {
    file = sd.open(filename, FILE_READ);
    if (!file) return false; // File not found

    size_t searchLen = strlen(searchString);
    size_t index = 0;
    pos = 0;

    while (file.available()) {
        char ch = file.read();
        if (ch == searchString[index]) {
            index++;
            if (index == searchLen) { // Match found
                pos = file.position() - searchLen;
                file.close();
                return true;
            }
        } else {
            index = (ch == searchString[0]) ? 1 : 0; // Reset index or start new match (not foolproof)
        }
    }

    file.close();
    return false; // String not found
}

you would use it like this:

size_t position;
if (findStringInFile("data.txt", "18429874", position)) {
    Serial.print("String found at position: ");
    Serial.println(position);
} else {
    Serial.println("String not found");
}

Thanks Jackson, I'll try it

Thank you for helping, I will update the results after this

Hi Jackson, I have tried implementing the code,
is my writing correct?

following are the results


SdFat sd;
File file;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
if (!sd.begin()) return false; // Initialization failed
}
bool findStringInFile(const char *filename, const char *searchString, size_t &pos) {
    file = sd.open(filename, FILE_READ);
    if (!file) return false; // File not found

    size_t searchLen = strlen(searchString);
    size_t index = 0;
    pos = 0;

    while (file.available()) {
        char ch = file.read();
        if (ch == searchString[index]) {
            index++;
            if (index == searchLen) { // Match found
                pos = file.position() - searchLen;
                file.close();
                return true;
            }
        } else {
            index = (ch == searchString[0]) ? 1 : 0; // Reset index or start new match (not foolproof)
        }
    }

    file.close();
    return false; // String not found
}

void loop() {
  // put your main code here, to run repeatedly:
size_t position;
if (findStringInFile("data.txt", "18429874", position)) {
    Serial.print("String found at position: ");
    Serial.println(position);
} else {
    Serial.println("String not found");
}
}

missing the includes for the library

try something like this, with the serial monitor at 115200 bauds

#include <SdFat.h>

SdFat sd;

bool findStringInFile(const char *filename, const char *searchString, size_t &pos) {
  File file = sd.open(filename, FILE_READ);
  if (!file) return false; // File not found

  size_t searchLen = strlen(searchString);
  size_t index = 0;
  pos = 0;

  while (file.available()) {
    char ch = file.read();
    if (ch == searchString[index]) {
      index++;
      if (index == searchLen) { // Match found
        pos = file.position() - searchLen;
        file.close();
        return true;
      }
    } else {
      index = (ch == searchString[0]) ? 1 : 0; // Reset index or start new match (not foolproof)
    }
  }

  file.close();
  return false; // String not found
}

void setup() {
  Serial.begin(115200);
  if (!sd.begin()) {
    if (sd.card()->errorCode()) {
      Serial.println("SD initialization failed.");
    } else if (sd.vol()->fatType() == 0) {
      Serial.println("Can't find a valid FAT16/FAT32 partition.");
    } else {
      Serial.println("Can't determine error type");
    }
    return;
  }

  size_t position;
  if (findStringInFile("data.txt", "18429874", position)) {
    Serial.print("String found at position: ");
    Serial.println(position);
  } else {
    Serial.println("String not found");
  }
}

void loop() {}

sorry for my misunderstanding...
the result is

"SD initialization failed."

is there no need to declare "chipselect" on

const uint8_t SD_CHIP_SELECT = 4;

indeed - I typed that here β€” you need to pass the parameters as you did before

finally...I can find it...

Thank you very much Jackson for your help..
here is the final code

#include <SdFat.h>

SdFat sd;
SdFile file;

const uint8_t SD_CHIP_SELECT = 4;

bool findStringInFile(const char *filename, const char *searchString, size_t &pos) {
  File file = sd.open("data.txt", FILE_READ);
  if (!file) return false; // File not found

  size_t searchLen = strlen(searchString);
  size_t index = 0;
  pos = 0;

  while (file.available()) {
    char ch = file.read();
    if (ch == searchString[index]) {
      index++;
      if (index == searchLen) { // Match found
        pos = file.position() - searchLen;
        file.close();
        return true;
      }
    } else {
      index = (ch == searchString[0]) ? 1 : 0; // Reset index or start new match (not foolproof)
    }
  }

  file.close();
  return false; // String not found
}

void setup() {
  Serial.begin(115200);
  if (!sd.begin(SD_CHIP_SELECT, SPI_HALF_SPEED)) {
    if (sd.card()->errorCode()) {
      Serial.println("SD initialization failed.");
    } else if (sd.vol()->fatType() == 0) {
      Serial.println("Can't find a valid FAT16/FAT32 partition.");
    } else {
      Serial.println("Can't determine error type");
    }
    return;
  }

  size_t position;
  if (findStringInFile("data.txt", "18429875", position)) {
    Serial.print("String found at position: ");
    Serial.println(position);
  } else {
    Serial.println("String not found");
  }
}

void loop() {}

glad it helped

hi, anyone here?
I found a little problem..

When searching for data using the value sent from the Wiegand RFID, it seems like there are empty characters behind it...

so it doesn't match the values ​​in the list.

How do I remove the empty characters??

I used the trim() command but it couldn't and an error like this appeared

if (findStringInFile("data.txt",wg.getCode(), position)) {
    Serial.print("String found at position: ");
    Serial.println(position);
  } else {
    Serial.println("String not found");
  }
Compilation error: conversion from 'long unsigned int' to 'String' is ambiguous