Thanks for all of the help, pianorain, whiteflags, EVOEx and brewbuck.
For completeness, and for people searching the internet for an answer to a similar problem (like I was), the final code is pasted below.
Code:
#include <iostream>
#include <string>
#include <conio.h> //needed for getch()
#include <sstream>
#include <fstream>
using namespace std;
#define numLidarBeams 529 // Total LIDAR beams per scan
struct IMUobject{ // IMU data
float yaw;
float pitch;
float roll;
};
struct GPSobject{ // GPS data
int easting;
float northing;
float altitude;
float speed;
};
struct Lidarobject{ // LiDAR
int Readings [numLidarBeams];
};
struct Dataobject{
IMUobject curIMU;
GPSobject curGPS;
Lidarobject curLidar;
};
int main()
{
//Initialisation
int desiredImageNumber = 9;
int imgNum; // Initialise the integer for the found image number value
int bufferSize = 500;
string searchString("image");
long int currentPtrPosn; // Where the pointer is up to searching
int eofPtrPosn;
Dataobject curData;
ifstream inFile; // Initiate the input file stream
inFile.open("C:\\datafile.txt", ifstream::in);
inFile.seekg (0, ios::end); // Go to the end of the file
eofPtrPosn = inFile.tellg(); // Store the end of file address to an integer
eofPtrPosn = eofPtrPosn;
currentPtrPosn = inFile.tellg(); // IF ONLY I KNEW HOW TO DO THINGS INITIALLY THEN DO A LOOP
while (desiredImageNumber != imgNum){
char * buffer; // to store search search block of code
buffer = new char [bufferSize]; // allocate memory
// go back one buffer size in the text file (the 11 accounts for the possible overlap
// of "image #####" across the buffer ends except for the first read at the end of file
if(eofPtrPosn == currentPtrPosn){
currentPtrPosn = eofPtrPosn - bufferSize;
}else{
currentPtrPosn = currentPtrPosn - bufferSize + 11;
}
inFile.seekg (currentPtrPosn);
currentPtrPosn = inFile.tellg();
// read data into buffer
inFile.read (buffer,bufferSize);
//display buffer read
cout << "The contents of the buffer are: " << endl;
cout << "________________________________________" << endl;
cout.write (buffer,bufferSize);
cout << endl << "________________________________________" << endl;
// Put contents of buffer into a string
string bufferString(buffer);
// size_type imageStringAddr is the location of the first string matching searchString
//IN the string bufferStringfound by .find
string::size_type imageStringAddr = bufferString.find(searchString, 0);
if (imageStringAddr != string::npos){ // If the location of the first string is not at the end of the string
// This makes a string out of the characters following the space after "image"
string numberString = bufferString.substr(imageStringAddr + searchString.size() + 1);
// stringstream provides an interface to manipulate strings as if they were input/output streams.
stringstream numberStream(numberString);
if((numberStream >> imgNum).fail()){ // Convert stream to integer
cout << "ERROR: Failed string to integer conversion";
}
cout << "imgNum integer: " << imgNum << endl;
// Find the number of digits in imgNum
int imgNumDigits = 0;
int step = 1;
while (step <= imgNum) {
imgNumDigits++;
step *= 10;
}
// The "+2" accounts for buffer overlap, not sure why - "\n"? perhaps?
inFile.seekg (currentPtrPosn + imageStringAddr + searchString.size() + imgNumDigits + 2);
}
delete[] buffer;
}
inFile >> curData.curGPS.easting;
cout << "easting: " << curData.curGPS.easting << endl;
inFile >> curData.curGPS.northing;
inFile >> curData.curGPS.altitude;
inFile >> curData.curGPS.speed;
inFile >> curData.curIMU.roll;
inFile >> curData.curIMU.pitch;
inFile >> curData.curIMU.yaw;
for(int i=0; i<numLidarBeams; i++){
inFile >> curData.curLidar.Readings[i];
}
cout << "curData.curLidar.Readings[528]: " << curData.curLidar.Readings[528] << endl;
inFile.close();
getch();
return 0;
}
Many thanks to all those who helped with advice!