Reading Specific Record from a Data File

hi everyone,

I am trying to read a specific record from a file.

The "nutri.dat" was written by using a class that iterated to write the user input. Now I want to read the third iteration and print it on the screen but it's not executing like I want it to. Please help.

Thank you

-------------------------------------------------------------------------------

#include <iostream>
#include <iomanip>
#include <fstream>

using namespace std;

//Define a data structure named NutritionData

const int NAME_SIZE = 40;
struct NutritionData {
char foodName[NAME_SIZE];
double servingSize;
double calFromCarb;
double calFromFat;
double calFromProtein;
};


bool retrieveNutritionData(const string &fileName,
NutritionData *dataPtr,
int recordNum);
void printNutritionData(const NutritionData *dataPtr);

int main() {
string filename = "nutri.dat";
NutritionData *pointer = new NutritionData;
int record{4};

if(retrieveNutritionData(filename, pointer, record)!= 0){
printNutritionData(pointer);
}
else
cout << "The desired structure cannot be extracted." << endl;

return 0;
}

//***********************************************************************
//* Definition of the function that can retrieve a nutrition data.
//*
//* The function has the following parameters:
//*
//* fileName - a const string reference parameter for the file name.
//*
//* dataPtr - a pointer to the callers NutrititionData variable
//* for returning the retrieved NutritionData.
//* recordNum - a parameter for the desired structure.
//*
//* The parameter recordNum must be a positive integer.
//* If the value is 1, the function will attempt to return the first
//* structure on file. If the value is 2, the function will attempt to
//* return the second structure on file. And so on.
//*
//* The function returns true if the desired record has been
//* successfully retrieved from the file, otherwise it returns false.
//*
//***********************************************************************

bool retrieveNutritionData(const string &fileName,
NutritionData *dataPtr,
int recordNum) {
ifstream input;

input.open(fileName, ios::in |ios::binary);
bool result {false};

if(!input){
cout << "The file " << fileName << " cannot be opened." << endl;

}else{
cout << "Hello from function." << endl;
input.seekg(recordNum, ios::beg);
input.read((char*) dataPtr[recordNum].foodName, sizeof(dataPtr));
input.read((char*) dataPtr[recordNum].servingSize, sizeof(dataPtr));

result = true;

}


return result;
}

//***********************************************************************
//* Definition of the function that can print a nutrition data.
//* The function calculates the total calories per serving by
//* adding the calories from three nutrition components.
//*
//* The function has the following parameter.
//*
//* dataPtr - a pointer to the callers NutrititionData variable.
//*
//***********************************************************************
void printNutritionData(const NutritionData *dataPtr) {
cout << dataPtr->foodName << endl;
cout << dataPtr->servingSize << endl;
cout << dataPtr->calFromCarb << endl;
cout << dataPtr-> calFromFat << endl;
cout << dataPtr-> calFromProtein << endl;

}
Last edited on
input.seekg(recordNum, ios::beg);
You need to seek the number of records * size of records
And the input.read() statements are reading the size-of-a-pointer worth of data (sizeof(dataPtr)) when the size needs to be that of the relevant struct member.

Andy

PS As you're reading structs member by member, it might be worthwhile reading up about struct packing?

The forgotten art of Struct Packing in C/C++.
http://www.joshcaratelli.com/blog/struct-packing

For Microsoft Visual Studio, see:

pack pragma
https://docs.microsoft.com/en-us/cpp/preprocessor/pack?view=vs-2019

(I'm not familiar with other toolsets)
Last edited on
Also read this -> https://www.cplusplus.com/articles/jEywvCM9/
You attract more interest if you post "honey" rather than "vinegar".
Topic archived. No new replies allowed.