Text from file not reading into arrays - c++

This portion of my program is intended to read in a list of names and grades of students, then average them together and display them.
I declared a function as such:
int loadStudentNamesGrades(string students[], int grades[][MAX_GRADES],
string fileName, int maxStudents);
Here is the Definition:
int loadStudentNamesGrades(string students[],
int grades[][MAX_GRADES],
string fileName,
int maxStudents)
{
ifstream inFile; // input file stream
string nameFile; // name of file
string studentName; // name of student
int numStudents = 0; // number of students initialized to 0
inFile.open(fileName); // open the file
if (!inFile)
{
cout << "Unable to Open File!\n";
system("PAUSE");
exit (EXIT_FAILURE);
}
for (int i = 0; i < maxStudents && (inFile >> studentName >> numStudents);
i++, numStudents++)
{
for (int j = 0; j < MAX_GRADES; j++)
{
inFile >> grades[i][j];
}
students[i] = studentName;
}
inFile.close();
return numStudents;
}
When I try to run my program, my menu displays but none of the values from the text file populate. As far as I know my file is opening properly because it does not return an error.

It looks like it reads into the arrays, but you are not returning those. Try passing your arrays by reference, something like this:
int loadStudentNamesGrades(string (&students)[10], int (&grades)[10][MAX_GRADES],
string fileName, int maxStudents)
You could also think about using vectors instead of arrays.

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++;
}

I need to write a program that reads a file which will output all unique integers, if the integer has been seen already it will be dismissed

#include<iostream>
#include<fstream>
using namespace std;
void read_file(fstream &file);
int main()
{
fstream inFile;
inFile.open("Data.txt");
if (inFile.fail())
{
cerr << "Error with opening file";
exit(1);
}
else
{
read_file(inFile);
}
inFile.close();
return 0;
}
void read_file(fstream &file)
{
int arr[100];
fstream inFile;
int number;
int number_trash;
int number_hold;
while (!inFile.eof())
{
for (int i = 0; i < 101; i++)
{
inFile >> number;
number_hold = number;
if (number != number_hold)
{
arr[i] = number;
cout << arr[i] << endl;
}
else
{
number_trash = number;
}
}
}
}
In your read_file() function, you're passing an fstream instance of an already open file, which is correct, however, later in the same function, you declare a new instance of fstream called inFile which is not open and you're trying to read from this file stream.
Remove the fstream inFile and read from the file which your function takes as an argument.
Also, your algorithm is not correct - the first if statement condition will be always evaluated to false. You're assigning number to number_hold and then you're checking for their non-equality.
As a solution, consider something like this:
void read_file(fstream &file)
{
set<int> arr; // storage for your unique numbers
while (!file.eof())
{
int number;
file >> number; // read the number
// check if this number is already in your unique list
if (arr.find(number) == arr.end()) { // If it isn't, print it out...
cout << number << endl;
arr.insert(number); // ...and put it to your unique list
}
}
}
Note that for this to work you have to include another header file called set
#include <set>

filling an array of structs from a file

I am trying to fill an array of structs from a given file but it doesn't seem to read anything.
/******************************************************************
* READ FILE
* This function opens the given file name and saves the info
* into an array.
******************************************************************/
int readFile(const std::string dataFile, AccessRecord accessRecordArray[], int &cou\
nt)
{
std::ifstream fin(dataFile.c_str());
if (fin.fail())
return -1;
std::string file;
while (!fin.eof())
{
fin >> file;
count++;
}
std::cout << count << std::endl;
for (int i = 0; i < count; i++)
{
fin >> accessRecordArray[i].fileName;
fin >> accessRecordArray[i].userName;
fin >> accessRecordArray[i].timeStamp;
}
fin.close();
return 0;
}
All this outputs is zero equal to the variable count. Can you help me see what I am missing?

Reading selected values from a file and writing them in a new file in c++

I wanted to take user input(integer value) from keyboard and writing them in a file.Then, to select the values from 18-80 and writing in another file.My program runs till keyboard input and writing them in a file. But I don't know how to select some values under condition and writing them in another file.
#include<iostream>
#include<fstream>
using namespace std;
int main()
{
ofstream age;
age.open("age.txt",ios::out);
cout<<"Input the ages from keyboard: "<<endl;
for(int i=0;i<3;i++)
{
int n;
cin>>n; //value inputted from keyboard
age<<n<<endl;
}
ifstream agein;
agein.open("age.txt"); //Reading that existing file
ofstream ageout;
ageout.open("information.txt"); //writing in another file
{
int m;
if(m>18 && m<=80) //picking value from 18-80
ageout<<m<<endl;
}
age.close();
agein.close();
ageout.close();
return 0;
}
Don't forget to close your file before reopening it, even if you switch from read/write.
Here you go:
using namespace std;
int main()
{
ofstream age;
age.open("age.txt", ios::out);
cout << "Input the ages from keyboard: " << endl;
for (int i = 0;i<3;i++)
{
int n;
cin >> n; //value inputted from keyboard
age << n << endl;
}
age.close();// Do NOT forget that before reopening it
ifstream agein;
agein.open("age.txt"); //Reading that existing file
ofstream ageout;
ageout.open("information.txt");//writing in another file
if(ageout)//Checks if the file exists
{
string str;
int m;
while (agein >> m) //Get an int from a file
if (m>18 && m <= 80) //picking value from 18-80
ageout << m << endl;
}
agein.close();
ageout.close();
return 0;
}

Avoiding the use of eof in this case

I have posted the following code where I am reading from an input file -- storing information in a structure -- and then writing to an output file. I know that the eof function is not safe and hence one must use the getline function to check whether the end of file has been detected or not; however, in this particular code, I have not been able to use the getline function and hence has finally relied on the eof function. Hence, can you please suggest an alternative to the eof function or let me know how I can use the getline function when I am trying to initialize an array of structures . I have used two asterisk symbols to indicate where I want to use the getline function.
#include <iostream>
#include <fstream>
using namespace std;
//student structure
struct student
{
char name[30];
char course[15];
int age;
float GPA;
};
ifstream inFile;
ofstream outFile;
student getData();
void writeData(student writeStudent);
void openFile();
int main (void)
{
const int noOfStudents = 3; // Total no of students
openFile(); // opening input and output files
student students[noOfStudents]; // array of students
// Reading the data from the file and populating the array
for(int i = 0; i < noOfStudents; i++)
{
if (!inFile.eof()) // ** This where I am trying to use a getline function.
students[i] = getData();
else
break ;
}
for(int i = 0; i < noOfStudents; i++)
writeData(students[i]);
// Closing the input and output files
inFile.close ( ) ;
outFile.close ( ) ;
}
void openFile()
{
inFile.open("input.txt", ios::in);
inFile.seekg(0L, ios::beg);
outFile.open("output.txt", ios::out | ios::app);
outFile.seekp(0L, ios::end);
if(!inFile || !outFile)
{
cout << "Error in opening the file" << endl;
exit(1);
}
}
student getData()
{
student tempStudent;
// temp variables for reading the data from file
char tempAge[2];
char tempGPA[5];
// Reading a line from the file and assigning to the variables
inFile.getline(tempStudent.name, '\n');
inFile.getline(tempStudent.course, '\n');
inFile.getline(tempAge, '\n');
tempStudent.age = atoi(tempAge);
inFile.getline(tempGPA, '\n');
tempStudent.GPA = atof(tempGPA);
// Returning the tempStudent structure
return tempStudent;
}
void writeData(student writeStudent)
{
outFile << writeStudent.name << endl;
outFile << writeStudent.course << endl;
outFile << writeStudent.age << endl;
outFile << writeStudent.GPA << endl;
}
You want to write an operator>> for your student type. Something like:
std::istream& operator>>(std::istream& in, student& s) {
in >> s.age; // etc.
return in;
}
Which then allows you to write:
int studentNo = 0;
students[maxStudents];
while (studentNo < maxStudents && (in >> students[studentNo]))
++studentNo;
Why not write this way?
instead of
inFile.getline(tempStudent.name, '\n');
inFile.getline(tempStudent.course, '\n');
inFile.getline(tempAge, '\n');
You may
while(inFile.getline(tempStudent.name, '\n'))
{
inFile.getline(tempStudent.course, '\n');
inFile.getline(tempAge, '\n');
//do stuffs
}