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.
Related
#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>
I'm sorry this is a repeat question, but no solutions seem to work for my code.
This is for an assignment in school on reading from a file and copying the data to an array. An exception is thrown every time I try to edit the array "arr" in main.
Here's my code:
#include <iostream>
#include <fstream>
using namespace std;
struct Student {
string name;
float gpa;
int id;
};
void PrintStudents(Student arr[], int nstudents) {
for (int i = 0; i < nstudents; i++) {
cout << "Student name: " << arr[i].name << endl;
cout << "Student GPA: " << arr[i].gpa << endl;
cout << "Student ID: " << arr[i].id << endl;
}
}
int ReadStudents(string fname, Student arr[]) {
ifstream file;
file.open(fname);
int counter = 0;
string name_local;
float gpa_local;
int id_local;
int index = 0;
while (!file.eof()) {
if (counter == 0) {
file >> name_local;
}
else if (counter == 1) {
file >> gpa_local;
}
else if (counter == 2) {
file >> id_local;
}
counter++;
if (counter == 3) {
counter = 0;
Student newStudent = { name_local, gpa_local, id_local };
arr[index] = newStudent;
index++;
}
}
file.close();
return index;
}
void fillStudentArray(Student array[], int array_size) {
Student temp = { "", 0, 0 };
for (int i = 0; i < array_size; i++) {
array[i] = temp;
}
return;
}
int main() {
Student arr[128];
fillStudentArray(arr, 128); // exception thrown here??
cout << "Array filled." << endl;
cout << "Reading students" << endl;
int nstudents = ReadStudents("csci10.hw8.students.txt", arr);
PrintStudents(arr, nstudents);
return 0;
}
Thanks for any help! I'm totally stumped.
Edit: Woah, I left for a 30 minute coffee break and came back to a ton of answers! I'll try to respond to all of them.
Edit 2: Just got a solution! I was working in VS 2019, switched to old school terminal G++ and it worked! Thanks everyone for all the answers :)
You do not check the file was successfully opened. Try this:
ifstream file( fname );
if ( !file )
return -1;
You do not need local variables for reading. Read directly in your array elements:
file >> arr[index].name
ReadStudents ignores the size of the passed array: you might get in trouble if you read more than the allocated size (read this again). You might use std::vector, if allowed. Alternatively, pass the size, too – the same way you did for fill.
The way you are trying to read from file is overly complicated. Try a more c++ approach:
Define an extraction operator for Student:
std::istream& operator>>( std::istream& is, Student& s )
{
return is >> s.name >> s.gpa >> s.id;
}
Use it like you would use it for reading an integer:
file >> arr[ index ]
Alternatively you could use:
is >> arr[ index ].name >> arr[ index ].gpa >> arr[ index ].id
You will get something like this:
int ReadStudents( string fname, Student arr[]/*how large is the array?*/ )
{
ifstream file( fname );
if ( !file )
return -1;
int index = 0;
while ( file >> arr[ index ].name >> arr[ index ].gpa >> arr[ index ].id )
index++;
return index;
}
Explanation
If the stream does not get opened successfull, you get an endless loop. You never check if the reading operations are successfull. If they are not you never reach eof but keep incrementing index and write to array indices out of bounds. Also the counter is superfluos here.
Furthermore I would suggest to use a std::vector instead of an array and use push_back(). This makes sure, you don't write out of bounds.
(Possible) solution
This loop:
while (!file.eof()) {
if (counter == 0) {
file >> name_local;
}
else if (counter == 1) {
file >> gpa_local;
}
else if (counter == 2) {
file >> id_local;
}
counter++;
if (counter == 3) {
counter = 0;
Student newStudent = { name_local, gpa_local, id_local };
arr[index] = newStudent;
index++;
}
}
should be changed (with the function definition) to:
int ReadStudents(string fname, std::vector<Student> &vec)
{
// open stream, etc.
while (file >> name_local >> gpa_local >> id_local) {
Student newStudent = { name_local, gpa_local, id_local };
vec.push_back(newStudent);
}
// cleanup
}
To explain a bit further what the while (file >> name_local >> gpa_local >> id_local) does:
Since std::ifstream::operator>> returns a reference to the stream itself, you can chain those statements together.
The last reference gets implicitly converted to bool (or void* in c++11 or earlier) as seen here. This evaluates true if the last reading operations where successfull (so name_local, gpa_local and id_local now have valid values) and the stream is ready for IO-operations (so it didn't reach eof while reading). This implies that it's also checking if the stream was opened at all.
Once those conditions are met you can create a new element and push it into the vector.
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
I get this error " 0xC0000005: Access violation writing location 0xfeeefeee" in c++ program.
My code is
#include<iostream>
#include<fstream>
#include<string>
using namespace std;
class Employee
{
public:
string name;
int age;
int phone;
int salary;
};
int main()
{
Employee emp1;
ofstream f1;
f1.open("qwe.txt",ios::binary|ios::app);
for(int i=0;i<2;i++)
{
cout<<"enter name:\t";
cin>>emp1.name;
cout<<"enter age:\t";
cin>>emp1.age;
cout<<"enter phone:\t";
cin>>emp1.phone;
cout<<"enter salary:\t";
cin>>emp1.salary;
cout<<"\n";
f1.write((char *)(&emp1),sizeof(Employee));
}
f1.close();
Employee emp2;
ifstream f2;
f2.open("qwe.txt",ios::binary|ios::in);
while(f2)
{
f2.read((char *)(&emp2),sizeof(Employee));
if(f2.eof())
{
break;
}
else
{
cout<<"\n"<<emp2.name;
cout<<"\n"<<emp2.age;
cout<<"\n"<<emp2.phone;
cout<<"\n"<<emp2.salary<<"\n";
}
}
f2.close();
cin.get();
return 0;
}
I think the problem is in while(f2). But I am not sure. This line f2.read((char *)(&emp2),sizeof(Employee)) may create problem. But I need this line.
You could not read/write structures with a complex types, like std::string that way. They have an internal structure which is implementation specific. Directly overriding its memory is a surest way to shoot yourself in the foot. Use >>/<< operators instead:
f1 << emp1.name;
f1 << emp1.age;
//...
f2 >> emp2.name;
f2 >> emp2.age;
The internal representation of a class is implementation defined. Additionally the string member can hold the data in the member directly or in an additional heap object depending of the number of charaters.
That's why you need a serialization of instances of your class. The serialize function will take serialization target like ofstream an writes a represenation of the data. The deserialization function will take a serialization source like ifstream and reads the reprensentation to the members.
If you need a low level API as used in your code(read/write) check out:
Be careful, the following line can break your data, I was changed this to avoid the previous valued writed by you.
f1.open("qwe.txt", ios::binary | ios::trunc);
Complete code:
#include <iostream>
#include <fstream>
#include <string>
#include <cstring>
using namespace std;
class Employee {
public:
string name;
int age;
int phone;
int salary;
};
int main() {
Employee emp1;
ofstream f1;
f1.open("qwe.txt", ios::binary | ios::trunc);
for (int i = 0; i < 2; i++)
{
cout << "enter name:\t";
cin >> emp1.name;
cout << "enter age:\t";
cin >> emp1.age;
cout << "enter phone:\t";
cin >> emp1.phone;
cout << "enter salary:\t";
cin >> emp1.salary;
cout << "\n";
size_t lenght = emp1.name.size();
char lenghtval[sizeof(lenght)];
std::memcpy(&lenghtval, &lenght, sizeof(lenght));
f1.write(lenghtval, sizeof(lenght));
const char *name = emp1.name.c_str();
f1.write(name, static_cast<int>(lenght));
int val = emp1.age;
char towrite[sizeof(val)];
std::memcpy(&towrite, &val, sizeof(val));
f1.write(towrite, sizeof(val));
val = emp1.phone;
std::memcpy(&towrite, &val, sizeof(val));
f1.write(towrite, sizeof(val));
val = emp1.salary;
std::memcpy(&towrite, &val, sizeof(val));
f1.write(towrite, sizeof(val));
}
f1.close();
Employee emp2;
ifstream f2;
f2.open("qwe.txt", ios::binary | ios::in);
while (f2) {
size_t lenght = 0;
char lenghtval[sizeof(lenght)];
f2.read(lenghtval, sizeof(lenght));
std::memcpy(&lenght, lenghtval, sizeof(lenght));
char name[lenght + 1];
f2.read(name, static_cast<int>(lenght));
name[lenght] = '\0';
emp2.name = name;
int val = 0;
char toread[sizeof(val)];
f2.read(toread, sizeof(val));
std::memcpy(&val, toread, sizeof(val));
emp2.age = val;
f2.read(toread, sizeof(val));
std::memcpy(&val, toread, sizeof(val));
emp2.phone = val;
f2.read(toread, sizeof(val));
std::memcpy(&val, toread, sizeof(val));
emp2.salary = val;
if (f2.eof()) {
break;
}
cout << "\n" << emp2.name << std::endl;
cout << "\n" << emp2.age;
cout << "\n" << emp2.phone;
cout << "\n" << emp2.salary << "\n";
}
f2.close();
cin.get();
return 0;
}
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
}