C++ filling array of structure from file - c++

Hi I need to read a file and get data from file to array of structure.
Structure
struct Activity {
string ID;
string Name;
string quantity; };
I have this function for reading from file
int* fillStructure(ifstream &fileActivity){
int i=0;
int numberOfElements = numberOfLines(fileActivity);
Activity* myActivity = new Activity[numberOfElements];
while (i < numberOfElements)
{
getline(fileActivity, myAktivity[i].ID, ',');
getline(fileActivity, myActivity[i].Name, ',');
getline(fileActivity, myActivity[i].quantity, '\n');
i++;
}
fileActivity.close();
return myActivity; }
And when i try in main function to print members of structures It doesnt work
int main(){
if (!(fileActivity.is_open())){
cout << "Error when reading file" << endl;
return 0;
}
fillStructure(fileActivity);
cout << myActivity[1].ID << endl; return 0; }
I am beginner, can you guys help me what I am doing wrong ?

You declared myActivity in void fillStructure(ifstream &fileActivity), but trying to access from int main().

You have to declare your return value in the main function.
struct Activity {
string ID;
string Name;
string quantitiy;
};
Activity* fillStructure(ifstream &fileActivity) {
int i = 0;
int numberOfElements = numberOfLines(fileActivity);
Activity* myActivity = new Activity[numberOfElements];
while (i < numberOfElements)
{
getline(fileActivity, myActivity[i].ID, ',');
getline(fileActivity, myActivity[i].Name, ',');
getline(fileActivity, myActivity[i].quantitiy, '\n');
i++;
}
fileActivity.close();
return myActivity;
}
int main(){
ifstream fileActivity ("test.txt", ifstream::in);
Activity* retFile;
retFile = fillStructure(fileActivity);
cout << retFile[1].ID << endl;
return 0;
}
Declare the return Type of the fillStructure function in the main function like this:
Activity* retFile;
This codesnippet works for me

Related

Parse (split) a txt file with a string and int in c++

im a Student and new to this site. I want to split my txt file with my highscore data back to my Highscore List.
The txt file stores my Highscore like name:score
My parsing is not working and i dont know why?
I just want to split it to name and score again and then put it in my HighscoreList.
If you have any question about the code just ask :)
#include "highscore.h"
highscore::highscore(){
}
struct highscore::Player{
string spielerName;
int score;
};
void highscore::writeHighscore(string name, int score ,int playerNumberx){
Player HighscoreListe[100];
for(int i=0;i<=99;i++){
HighscoreListe[i].score = {0};
}
for(int i=0;i<=99;i++){
HighscoreListe[i].spielerName = "leer";
}
HighscoreListe[playerNumberx].spielerName = name;
HighscoreListe[playerNumberx].score = score;
int i, j,temp;
string temp1;
ifstream myfile("scores.txt");
string line;
//heres the point where i need help!!
if (myfile.is_open()){
int z=0;
while(getline(myfile, line)){
string name1;
string score1;
int d = 20;
while(line[z] != ':'){
name1 += line[z];
z++;
}
z = z+2;
while(line[z] != '\0'){
score1 += line[z];
z++;
}
HighscoreListe[d].spielerName = name;
HighscoreListe[d].score = score;
d++;
}
myfile.close();
}else cout << "Unable to open file" << endl;
for(i = 0; i<100; i++) {
for(j = i+1; j<100; j++)
{
if(HighscoreListe[j].score < HighscoreListe[i].score) {
temp = HighscoreListe[i].score;
temp1 = HighscoreListe[i].spielerName;
HighscoreListe[i].score = HighscoreListe[j].score;
HighscoreListe[i].spielerName = HighscoreListe[j].spielerName;
HighscoreListe[j].score = temp;
HighscoreListe[j].spielerName = temp1;
}
}
}
ofstream myfilex("scores.txt");
if (myfilex.is_open()){
for(int i = 99;i>89;i--){
myfilex << HighscoreListe[i].spielerName << ":" << HighscoreListe[i].score<<endl;
}
myfilex.close();
}
else cout << "Unable to open file" << endl;
}
void highscore::readHighscore(){
string line;
ifstream myfile("scores.txt");
if (myfile.is_open()){
while(getline(myfile, line)){
cout << line << endl;
}
}
else cout << "Unable to open file" << endl;
}
Make a >> overload for highscore::Player.
In the >> overload
Use std::getline to read a line from the input stream.
Create a std::istringstream out of the line.
Use std::getline to read up to the : from the istringstream into a local string name;.
Use another std::getline to read the rest of the line into a string.
Convert the string into an int with std::stoi and store into a local int score;. Make sure you provide a pos argument.
Ensure that the entire string was converted by comparting the pos argument with the string's length.
If nothing went wrong, store name and score into the highscore::Player passed by the caller. Otherwise, set the failbit on the input stream with setstate
return the input stream.
Now the reading code should be something simple like
int scorecount = 0;
while (myfile >> HighscoreListe[scorecount])
{
scorecount++;
}

Input from txt file doesn't match when it is read/passed second time (C++)

So I am fairly new to coding and c++. So...sorry if this is something very obvious to some of you:
I am having a hard time getting this code to read the input stored in txt file for a second time. It works for the first time.
void readcode(ifstream& infile, int list[], int& length, bool& lenCodeOk)
{
int count;
lenCodeOk = true;
infile >> length; //get the length of the secret code
cout << "Length1 is "<<length<<endl;
if (length > MAX_CODE_SIZE)
{
lenCodeOk = false;
return;
}
//Get the secret code.
for (count = 0; count < length; count++)
{
infile >> list[count];
}
cout<<" Code recorded is: ";
for (count = 0; count < length; count++)
{
cout<<list[count]<<" "<<endl;
}
}
So the first integer in my txt file is the length of the sequence of integers. This function does everything it is supposed to. Reads the length correctly also stores everything in an array.
However when I call the below compareCode function after calling the readcode function, it comes out with a completely random/different length2 (that changes/goes one up everytime I call) and array elements.
void compareCode(ifstream& infile, ofstream& outfile, const int list[], int length)
{
int length2;
int digit;
bool codeOk;
int count;
codeOk = true;
infile >> length2;
cout<<"Length2 is "<<length<<endl;
if(length != length)
{
cout<< "The original code and its copy are not of the same length"<<endl;
return;
}
outfile << "Code Digit Code Digit Copy"<<endl;
for (count= 0; count<length; count++)
{
infile >> digit;
outfile<<setw(5)<<list[count]<<setw(17)<<digit;
if (digit != list[count])
{
outfile << " Code digits are not the same"<<endl;
codeOk = false;
}
else
{
outfile<<endl;
}
if (codeOk)
{
outfile<<"Message transmitted OK."<<endl;
}
else
{
outfile<<"Error in transmission. "<<"Retransmit!!"<<endl;
}
}
}
It seems like I am missing an important piece of information about passing fstream variables I would really appreciate if someone pointed me towards the right direction.
int main()
{
int codeArray[MAX_CODE_SIZE];//Array to store the secret code
int codeLength;// Variable to store the length of the code
int codeLength2;
bool lengthCodeOk;//Variable to indicate if the legth of the secret code is less than or equal to 250
ifstream incode;// Declare ifstream variable
ofstream outcode;//Declare ofstream variable
char inputFile[51];//Variable to store the name of the input file
char outputFile[51]; //Variable to store the name of the output file
cout<<"Enter the input file name: "<<endl;
cin>> inputFile;//makesure it is one word because ci.>>skips white space
cout<<endl;
incode.open(inputFile);
if(!incode)
{
cout<< "Cannot open the input file."<<endl;
return 1;
}
cout<< "Enter the output file name: " ;
cin>> outputFile;//Same deal, one word so cin>> can read
cout<<endl;
outcode.open(outputFile);
readcode(incode,codeArray,codeLength,lengthCodeOk);
if (lengthCodeOk)
{
compareCode(incode,outcode,codeArray,codeLength);
}
else
{
cout<<"Length of the secret code must be <= "<<MAX_CODE_SIZE<<endl;
}
incode.close();
outcode.close();
return 0;
}
this should go like this:
istream& readcode(istream& infile, std::vector<int>& list)
{
int length;
if (infile >> length) {
list.reserve(length);
for (int count = 0; count < length; count++)
{
int x;
if (infile >> x)
{
list.push_back(x);
} else {
break;
}
}
}
return infile;
}
ifstream file("somefile.txt");
if (file.good())
{
std::vector<int> a, b;
if (readcode(file, a).good())
{
file.seekg(0);
if (readcode(file, b).good())
{
cout << (a!=b? "code reading are different" : "code reading are same") << endl;
}
else
{
cerr << "failed read again code" << endl;
}
}
else
{
cerr << "failed read code" << endl;
}
}

Load variable from string

How should i go about loading a variable from a string?:
for example, this is my text file:
int: 10
int: 25
int: 30
How could i load these into a array? this is the code i use to load the strings:
string loadedB[100];
ifstream loadfile;
loadfile.open("ints.txt");
if(!loadfile.is_open()){
MessageBoxA(0, "Could not open file!","Could not open file!", MB_OK);
return;
}
string line; int i = -1;
while(getline(loadfile, line)){ i++;
loadedB[i] = line;
}
loadfile.close();
for(int x = 0; x < count(loadedB); x++){
cout << loadedB[x] << endl;
}
I would like to do something like:
int intarray[100];
loadfromstringarray(loadedB, intarray);
That code would take the part of the string ( the numeric one ) and would put that value into the array, like intarray[0] = 10; and so on
EDIT: istringstream is the solution!
I personally like the good old std::istringstream object:
const std::string example = "int: 10";
std::string prompt;
int value;
std::istringstream parse_stream(example);
std::getline(parse_stream, prompt, ':');
parse_stream >> value;
I personally like the good old sscanf C function:
int intarray[100];
int i = 0;
while(getline(loadfile, line) && i < sizeof(intarray)/sizeof(*intarray))
{
sscanf(line.c_str(), "int: %d", intarray + i++);
}
Use stoi:
vector<int> ints;
ifstream loadfile("ints.txt");
string line;
while(getline(loadfile, line)) {
ints.push_back(stoi(line.substr(5))); // skip the first 5 chars of each line
}
for(int i : ints) {
cout << i << endl;
}
Output:
10
25
30

issue with text file reading and emty space passing in dynamic array

I need help in c++ with reading text from file into dynamic array.
File
Regbis
Vardenis Paverdenis
Jonas Puikuolis
Gediminas Jonaitis
Futbolas
Tadas Pilkius
Justas Julis
Tenisas
Ricerdas Berankis
I tried like this and another way with while and getline s.empty but it didn't work for me.
using namespace std;
struct struktura{
char team;
char lastname;
char firstname;
} sarasas[999];
int main()
{
char x [200];
int kiek;
ifstream duomenys;
duomenys.open("duom.txt");
int row, col;
while (!duomenys.eof())
{
cout << "How many teams" << endl;
cin >> row;
int **a = new int *[row];
for (int i = 0; i < row; i++)
{
cin >> col;
a[i] = new int[col];
}
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
duomenys >> a[i][j];
cout << a[i][j] << " ";
}
cout << endl;
}
}
system("Pause");
return 0;
}
Okay, this has quite a few problems. I'd start with using std::string for the strings, and std::vector for the dynamic array.
Then I'd work at defining the data structures at least halfway reasonably. I think the general idea is something like this:
struct team {
std::string name;
std::vector<std::string> players;
};
Then I'd define an operator>> for a team, something like this:
std::istream &operator>>(std::istream &is, team &t) {
std::vector<std::string> players;
std::string temp;
// If we can't read a team name, return signaling failure:
if (!std::getline(is, temp))
return is;
// save the team name
t.name = temp;
// and read the player's names:
while (std::getline(is, temp)) {
if (temp.empty()) // empty line--end of this team's players
break;
players.push_back(temp);
}
t.players = players; // Write the player's names into the destination
is.clear(); // and signal success, since we read a team's data
return is;
}
From there, we can read all the teams in a file:
std::ifstream in("teams.txt");
std::vector<team> teams { std::istream_iterator<team>{in},
std::istream_iterator<team>{} };

Having memory managment issue with file

I'm opening file in 1 function and trying to use pointer of that in other function. But i dunno why its not working.
Below is the Code.
void ReadFile()
{
float data;
int total_rows, pairs;
double longitude, latitude;
{
GsmFingreprintEuc *g;
ll.push_front(new GsmFingreprintEuc);
if(file_ptr.is_open())
cout<<"Yes!!"<<endl;
else
cout<<"NO!!"<<endl;
file_ptr >> data;
total_rows = data;
cout<<"Total Rows:"<<total_rows<<endl;
for (int i = 0; i < total_rows; i++)
{
g = ll.front();
file_ptr >> data;
pairs = data;
for (int j = 0; j < pairs; j++)
{
int id;
double value;
file_ptr >> data;
id = data;
file_ptr >> data;
value = data;
g->add_map(id, value);
}
file_ptr >> data;
latitude = data;
g->set_latitude(latitude);
file_ptr >> data;
longitude = data;
g->set_longitude(longitude);
}
}
cout<<"Size: "<<ll.size()<<endl;
}
DtFileReaderEuc(string file_path)
{
cout << "I am in Constructor" << endl;
cout << file_path << endl;
fstream file_ptr(file_path.c_str(), std::ios_base::in);
if (file_ptr.is_open()) {
cout << "Yahhy!! file Opend successfully" << endl;
float data;
file_ptr >> data;
double total_rows = data;
cout<<"Total Rows:"<<total_rows<<endl;
//file_ptr = myfile;
ReadFile();
//myfile.close();
} else
cout << "Wohoo!! Wrong path" << endl;
cout << "Done!!" << endl;
}
};
and when i rund this code output is:
"I am in Constructor
/home/umar/Desktop/DataFile/dha_dataset.gfp
Yahhy!! file Opend successfully
Total Rows:7257
NO!!
Total Rows:0
Size: 1
Done!!"
Thanks in advance
fstream file_ptr(file_path.c_str(), std::ios_base::in);
This is a new fstream variable local to your constructor. You probably meant to use the private variable of the same name.
Probably, in order to make the code compile you have put a fstream file_ptr somewhere you could see it from ReadFile but you forgot to remove the local copy in DtFileReaderEuc.
In this case you use the local version in DtFileReaderEuc and the "global" one in the ReadFile which is not opened.
As someone already suggested to you, try pass file_ptr to ReadFile
The file_ptr scope is not clear. You have declared and defined the file_ptr in DtFileReaderEuc so you have to pass its pointer to inner function ReadFile, otherwise, declaration of file_ptr should be in outer scope and put the definition in DtFileReaderEuc.
create file_ptr a class member and initialize the same in ctor, then it can be used anywhere in the member functions.
To get the file pointer outside class use getter/setter functions.