function to stream certain name and number from txt file - c++

i made a file named clientFile.txt
the file contain this clientFile.txt. Content:
abcd abcd 123 1607325695
A AI 123 1607327861
the function below should show the content of the text file when the function called.
void displayFile()
{
string str1;
string str2;
string fileN = "clientFile.txt";
ifstream myfilein;
myfilein.open("clientFile.txt");
double balance;
int numAct = 0;
time_t transTime;
if(!myfilein){
cerr << "FIle could not be opened" << endl;
exit(1);
}
while(myfilein >> str1 >> str2 >> balance >> transTime){
cout << setw(15) << str1 << ' ' << setw(15) << str2 << ' '
<< setw(7) << balance << " " << ctime(&transTime);
numAct++;
}
myfilein.close();
cout << "Number of records in the file " << fileN << ": " << numAct << endl;
}
but when i call it on this int main:
int main(){
ofstream myfileout;
ifstream myfilein;
string firstName,lastName;
int i=0;
string FN[1000],LN[1000];
double actBalance,AB[1000];
time_t currentTime,CT[1000];
myfilein.open ("clientFile.txt");
void displayFile();
if(myfilein.fail()){
cout<<"Creating new files"<<endl;
myfileout.open ("clientFile.txt",ios::out);
myfileout.close();
exit(1);
}
while(myfilein>>firstName>>lastName>>actBalance>>currentTime){
FN[i]=firstName;
LN[i]=lastName;
AB[i]=actBalance;
CT[i]=currentTime;
i++;
}
myfileout.open("clientFile.txt",ios::app);
cout<<"Enter first name, last name, and balance:"<<endl;
while(cin>>firstName>>lastName>>actBalance){
createRecord(myfileout, firstName,lastName,actBalance);
}
void displayFile();
myfileout.close();
}
it didnt show me any of the file content.
can you guys help me?
im using dev c++ with TDM-GCC 4.9.2 64-bit release

In last lines of main() you just need to change
void displayFile();
to
displayFile();
Because with void you're declaring a function, not calling it.

Related

readFile function not working on second iteration with different argument - c++

I've written a readFile function for a project I'm working on. I call it once, load in a file and read in it's contents - works fine
However, when I try to load it a second time, attempting to change the file name - it loads it in, saves it to a static string 'path' that I access in a different function - but then the function is not printing the data
The question is, how do I change the file name, and read it in successfully on the second iteration? The part that has me stumped is that it works once, but not twice
Ive attempted to use cin.ignore(); cin.clear(); cin.sync() on the second iteration of fileName function - but none of them allow a separate file to be read successfully.
Minimum Reproducible Example:
#include <iostream>
#include <fstream>
#include <string>
#include <stdlib.h>
#include <vector>
#include <sstream>
#include <iomanip>
#include <iostream>
using namespace std;
static string path;
string opt;
void readFile();
int fileName();
void menu() { // put in while loop - while True
cout << "----------------------" << endl;
cout << "R(ead) -" << "Read File" << endl;
cout << "F(ile) -" << "Set Filename" << endl;
cout << "\nPlease select from the above options" << endl;
cin >> opt;
cout << "\nInput entered: " << opt << endl;
if (opt == "R") {
readFile();
}
if (opt == "F") {
fileName();
}
}
void readFile() { // doing this twice
ifstream readFile;
readFile.open(path);
if (!readFile.is_open()) {
cout << "Could not read file" << endl;
}
string str;
int i = 0;
while (getline(readFile, str))
{
if (str[0] != '/')
{
cout << "DEBUG: Line is - " << str << endl;
}
}
readFile.clear();
readFile.close();
menu();
}
int fileName() {
cout << "File path: ";
if (path != "") {
cin.ignore();
cin.clear();
cin.sync();
}
getline(cin, path);
ifstream file(path.c_str());
if (!file) {
cout << "Error while opening the file" << endl;
return 1;
}
cout << "(File loaded)" << endl;
cout << "Path contains: " << path << endl;
file.clear();
file.close();
menu();
}
int main()
{
fileName();
}
Sample text, saved as txt file and read in using path:
Data1.txt
// standard test file
123,Frodo inc,2006, lyons,"1,021,000.16",0.0,
U2123,Sam Inc,2006, lyons,"21,600.00",13.10,123
A721,Merry Inc,2604, Kingston,"21,600.10",103.00,
U2122,Pippin Inc,2612, reid,"21,600.00",0
U1123,Huckelberry corp,2612, Turner,"21,600.00",13.10,
Data2.txt
7101003,Mike,23 boinig road,2615,48000,12000,0
7201003,Jane Philips,29 boinig cresent,2616,47000,12000,0
7301003,Philip Jane,23 bong road,2615,49000,000,0
7401004,Peta,23 bong bong road,2615,148000,19000,0
7101205,Abdulla,23 Station st,2615,80000,21000,0
The problem comes from reading in one, and trying to read in the other after the first has been executed.
Enter Filename
Hit Readfile
Return to menu, hit Set Filename
Change to Data2.txt
Readfile again. Not working
My tutor told me "That's not how functions work in c++" but didn't elaborate further, and is unavailable for contact.
In general, do not use global variables. The path variable should be passed as a parameter, not kept as a global variable altered between function calls, as this leads to many side effects and is the source of countless bugs. See the following refactoring:
void menu() { // put in while loop - while True
while(true)
{
//Keep this as a local variable!
std::string opt;
std::string filename;
cout << "----------------------\n";
cout << "R(ead) -" << "Read File\n";
cout << "F(ile) -" << "Set Filename\n";
cout << "\nPlease select from the above options\n";
cin >> opt;
cout << "\nInput entered: " << opt << '\n';
if (opt == "R") {
readFile(filename);
}
if (opt == "F") {
filename = getFileName();
}
}
}
void readFile(const std::string & filename) {
ifstream readFile;
readFile.open(filename);
if (!readFile.is_open()) {
cout << "Could not read file " << filename << '\n';
}
string str;
int i = 0;
while (getline(readFile, str))
{
if (str[0] != '/')
{
cout << "DEBUG: Line is - " << str << '\n';
}
}
readFile.close();
//just return to get back to menu
return;
}
std::string getFileName() {
cout << "File path: ";
std::string path;
getline(cin, path);
ifstream file(path.c_str());
if (!file) {
cout << "Error while opening the file" << '\n';
//Instead of returning an error code use an exception preferably
}
cout << "(File loaded)" << '\n';
cout << "Path contains: " << path << '\n';
file.close();
return path;
}
Other notes:
Ideally, do input in output in just one function, not all three as it gets confusing exactly what each function is responsible for.
If you want something to hold a file and print the contents, you can use an class.
The file is checked if it is openable twice, not really any reason to do this just delegate that responsibility to one function.
One of the best things about C++ is RAII and deterministic lifecycles for objects and primitives - use it!! Do not give everything a long life with global variables - use smart parameters and return values instead.

Output from file using function

the title says it all
This is my code:
I have a class called House, where i define the values.
class HOUSE
{
public:
int id;
string 1;
string 2;
string 3;
int an;
};
template<class Type>
class table
{
public:
vector<Type> V;
//double inceput;
//double sfirsit;
//int comparatii;
//int interschimbari;
public:
table();
void print();
void liniar();
};
template<class Type>
table<Type>::table()
{
ifstream file("file.txt");
ifstream file1("file1.txt");
if (file.fail() || file1.fail())
{
cerr << "Eroare la deschiderea fisierului!" << endl;
_getch();
exit(1);
}
HOUSE* value = new HOUSE;
while (!file.eof() || file1.fail())
{
file >> value->id;
file >> value->tara;
file >> value->brand;
file >> value->culoare;
file >> value->an;
this->V.push_back(*value);
}
file.close();
}
The print function for the values
template<class Type>
void table<Type>::print()
{
cout << endl << setw(50) << "AFISAREA DATELOR" << endl;
cout << setw(5) << "Id" << setw(15) << "1" << setw(20) << "2" << setw(17) << "3" << setw(20) << "an" << endl << endl;
for (int i = 0; i < this->V.size(); i++)
{
cout << setw(5) << this->V.at(i).id << setw(15)
<< this->V.at(i).1<< setw(17)
<< this->V.at(i).2<< setw(17)
<< this->V.at(i).3<< setw(25)
<< this->V.at(i).an << endl;
}
cout << endl << "Dimensiunea tabelului n= " << V.size() << endl;
}
{
file >> value->id;
file >> value->1;
file >> value->2;
file >> value->3;
file >> value->an;
this->V.push_back(*value);
}
file.close();
}
in main
int main() {
table<MOBILE>* file = new table<MOBILE>();
table<MOBILE>* file1 = new table<MOBILE>();
file ->print();
file1 ->print();
This is full code as requested.
Need make it somehow print the data from file1 and file2 .
thx
The problem is idk if called right. Because
file ->print();
file1 ->print();
both print data from the file only
There are no errors at all
There's lots and lots wrong with your code. but I'm going to ignore that and just answer what I think is your actual question.
You want two table objects, one of which reads from file.txt and the other reads from file1.txt. To do that you should pass the file name into the table::table constructor, so it knows which file to read from. Like this
template<class Type>
class table
{
...
public:
table(const char* filename); // constructor takes filename parameter
...
};
template<class Type>
table<Type>::table(const char* filename)
{
ifstream file(filename); // open filename
if (file.fail())
...
int main() {
table<MOBILE>* file = new table<MOBILE>("file.txt"); // read from file.txt
table<MOBILE>* file1 = new table<MOBILE>("file1.txt"); // read from file1.txt
file ->print();
file1 ->print();
}

Unable to opening file with ifstream

I'd like to get some assistance regarding the following line of code.
for the function constructArray,I'm unable to run it as shows the !aFile as true message but I have no idea what's the error.
Really appreciative of your assistance
Also how do I create inFile fileName with .txt,i've tried indentation with +".txt" but due to the file type in the argument i'm unable to do so.
Compiler run image: https://imgur.com/a/wkGwL
using namespace std;
enum NumType {Odd, Even};
struct Number
{
int no;
NumType type;
int oddDigits;
int evenDigits;
int sumDigits;
int noDigits;
};
// Create inFile data file with certain number of integers which are randomly generated
void constructInfile (fstream& aFile, char fileName[]);
// Read data from infile txt file and transfer to array of numbers
int constructArray (fstream& aFile,const char fileName[], Number ran[]);
/*
void processArray (Number [ ], int);
// Transfer information from array and store into output file called outfile txt with specific information format
void arrayToOutfile (fstream&, char [ ], Number [ ], int);
*/
const int MAX = 50;
int main()
{
srand(time(NULL));
fstream aFile;
char fileName [MAX];
cout << "Enter designated file name to be created" << endl;
cin >> fileName;
constructInfile (aFile,fileName);
Number ran[MAX];
int recNo = constructArray(aFile,fileName,ran);
cout << recNo << " of records transferred" << endl;
}
// Create inFile data file with certain number of integers which are randomly generated
void constructInfile (fstream& aFile,char fileName[]){
aFile.open(fileName, ios::out);
if(aFile.fail()){
cout << "File open unsuccessful" << endl;
aFile.close();
exit(1);
}
cout << "Begin creation of " << fileName << " file" << endl << endl;
int size = rand()%51+50;
for(int a = 0;a < size;a++){
aFile << rand()%1000+1 << endl;
}
cout << fileName << " file successfully created" << endl;
}
// Read data from infile txt file and transfer to array of numbers
int constructArray (fstream& aFile,const char fileName[], Number ran[]){
aFile.open (fileName, ios::in);
if (!aFile)
{
cout << fileName << " failed to open" << endl;
aFile.close ();
return 0;
}
cout << "Begin from " << fileName << " to array" << endl;
int i = 0;
char tabKey;
while (aFile >> ran[i].no)
{
aFile.get (tabKey); // read and discard
i++;
}
aFile.close ();
cout << fileName << " to array done" << endl;
return i;
}
You are opened a file in ios::out mode and never closed it!
Again you are trying to open the same file in ios::in mode. How a file could be opened twice in 2 different mode without properly closing the fstream?
You need to close the filestream inside the function constructInfile()!!!
You have opened the file but forget to close it. At the end of both of the functions, close the aFile. That should solve the problem.

C++ Vector of Struct using push_back

This is an assignment for a course that I am having problems with. Until now I thought I was fairly familiar with vectors in C++. This program is supposed to take a file from the user calculate the users pay then spit back out in a nice table all the information relevant.
It must contain a vector of struct and I must use push_back. I get two errors that I cannot figure out at this moment. In the for loop at the end of main() it tells me a reference type of vector cannot be initialized with Employee. The two functions after ward tell me that I for example .HoursWorked is not a member of the struct.
I tried looking around other questions for help but they all mentioned not using pointers which I'm 100% positive there are no pointers in my program. The txt file I am using for testing the program looks as follows:
John Smith 123-09-8765 9.00 46 F
Kevin Ashes 321-09-8444 9.50 40 F
Kim Cares 131-12-1231 11.25 50 P
Trish Dish 141-51-4564 7.52 24 P
Kyle Wader 432-12-9889 5.75 48 F
Code:
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <vector>
using namespace std;
struct Employee
{
string name;
string ssn;
double hourlyWage;
double HoursWorked;
char status;
double straightTimePay;
double overTimePay;
double netPay;
};
void calculatePay(vector<Employee>& buisness);
void displayEmployee(vector<Employee> buisness);
int main()
{
vector<Employee> buisness;
string fileName, line;
ifstream inFile;
stringstream ss;
cout << "Please input the file name to read: ";
cin >> fileName;
inFile.open(fileName);
if (!inFile)
{
cout << "Cannot open file " << fileName << " Aborting!" << endl;
exit(1);
}
int index = 0;
string firstName, lastName;
getline(inFile, line);
while (!inFile.eof())
{
if (line.length() > 0)
{
ss.clear();
ss.str(line);
buisness.push_back;
ss >> firstName >> lastName;
buisness[index].name = firstName + " " + lastName;
ss >> buisness[index].ssn;
ss >> buisness[index].hourlyWage >> buisness[index].HoursWorked;
ss >> buisness[index].status;
index++;
}
getline(inFile, line);
}
inFile.close();
cout << "The information of the buisness:" << endl;
cout << setw(20) << "Name" << setw(15) << "SSN" << setw(12) << "Hourly Wage";
cout << setw(14) << "Hours Worked" << setw(18) << "Straight Time Pay";
cout << setw(14) << "Over Time Pay" << setw(6) << "Status" << setw(10) << "Net Pay" << endl;
for (index = 0; index < buisness.size(); index++)
{
calculatePay(buisness[index]);
displayEmployee(buisness[index]);
}
return 0;
}
void calculatePay(vector<Employee>& buisness)
{
if (buisness.HoursWorked <= 40)
{
buisness.straightTimePay = buisness.hourlyWage * buisness.HoursWorked;
buisness.overTimePay = 0;
}
else
{
buisness.straightTimePay = buisness.hourlyWage * 40;
buisness.overTimePay = buisness.hourlyWage * 1.5 * (buisness.HoursWorked - 40);
}
buisness.netPay = buisness.straightTimePay + buisness.overTimePay;
if (buisness.status == 'F')
buisness.netPay -= 10;
}
void displayEmployee(vector<Employee> buisness)
{
int precisionSetting = cout.precision();
long flagSettings = cout.flags();
cout.setf(ios::fixed | ios::showpoint);
cout.precision(2);
cout << setw(20) << buisness.name << setw(15) << buisness.ssn << setw(12) << buisness.hourlyWage;
cout << setw(14) << buisness.HoursWorked << setw(18) << buisness.straightTimePay;
cout << setw(14) << buisness.overTimePay << setw(6) << buisness.status << setw(10) << buisness.netPay << endl;
cout.precision(precisionSetting);
cout.flags(flagSettings);
}
At the very least.. You have the line:
calculatePay(buisness[index]);
So clearly we all calling a function calculatePay and we're passing it an Employee.
But your function prototype says that it takes a std::vector<Employee>. You probably intended for the functions to take Employee & instead.
You should call vector push_back with the element to put in:
Employee employee;
// assign values to employee
ss << employee.ssn;
ss << employee.name;
business.push_back(employee);
Although the compiler error logs seem tedious, but you can almost always get enough information from the error logs. Compiling under gcc 4.2.1, the error logs says :
error: invalid initialization of reference of type ‘std::vector<Employee, std::allocator<Employee> >&’ from expression of type ‘Employee’ on the line of calling method calculatePay(). We can infer that you passed Employee to and function which want an vector of Employee as parameter. You can fix this by change calculatePay(vector<Employee>& buisness) to calculatePay(Employee& buisness). And that will fix error: ‘class std::vector<Employee, std::allocator<Employee> >’ has no member named ‘HoursWorked’

After dragging a file on exe, ifstream fails to open file

I have have the following problem:
When I drag and drop a file to my tool (exe) when ifstream fails to open the file.
If I give it manually though the console it works!
I don't get where the diffenence is, because I am cutting the path and passing just the filename.
Have a look at the code:
int main(int argc, char* argv[]) {
if (argc < 2) {
cout
<< "ERROR: Wrong amount of arguments! Give at least one argument ...\n"
<< endl;
cout << "\n" << "Programm finished...\n\n" << endl;
cin.ignore();
exit(1);
return 0;
}
vector<string> files;
for (int g = 1; g < argc; g++) {
string s = argv[g];
cout<<"parameter at: " << g << " = " << argv[g] << "\n" << endl;
string filename = "";
int pos = s.find_last_of("\\", s.size());
if (pos != -1) {
filename.append(s.substr(pos + 1));
// cout<<" cutted path: " << s.substr(0,s.size()-filename.size()) << endl;
// cout << "argv[1] " << argv[1] << endl;
cout << "\n filename: " << filename << "\t pos: " << pos << endl;
files.push_back(filename);
}
files.push_back(s);
}
for (unsigned int k = 0; k < files.size(); k++)
{
cout << "files.at( " << k << " ): " << files.at(k).c_str() << endl;
Converter a(files.at(k).c_str());
a.getCommandsFromCSV();
a.saveConvertedFile();
}
cout << "\n" << "Programm finished...\n\n" << endl;
cin.ignore();
return 0;
}
It fails already on the constructor:
Converter::Converter(const char* file) {
filename = file;
myfile.open(filename.c_str(), ios_base::in);
cout << (myfile ? "open successful on constructor " : "some error on constructor");
cin.ignore();
trace_raw = "";
}
You have any idea why?
UPDATE:
The file as parameter works now. The solution was to leave the full path.
Anyway I have the same error on a hard coded file. I thought it may be the same that's why I added .\ at the beginning of the file name... without success.
The code:
void GenericCommandConverter::getATCommandsFromCSV() {
cout << "\t| +++++++++++getATCommandsFromCSV() started+++++++++++++ |"
<< endl;
/*
* CSV file name is hardcoded
*/
string filename_csv = ".\\test.csv";
string commands = "";
int pos_start = 0;
int pos_end = 0; // "|"
int substrLength = 0;
int separator_count = 0;
char c;
vector<string> lines;
vector<string> commandList;
vector<vector<string> > linesSeparated;
ifstream csvFile;
csvFile.open(filename_csv.c_str(), ios_base::in);
cout << (myfile ? "open successful on getATCommandsFromCSV " : "some error on getATCommandsFromCSV ");
cin.ignore();
...
UPDATE2:
The solution was: on dropping a file to the exe, the "root" folder changes to the one where the dropped file comes from. Giving the hardcoded file the path from the *.exe solved it!
I am guessing your current directory is wrong. Don't cut the path off. Anyway you should do error checking / debugging to see why it couldn't open the file. Diligent debugging is essential for solving problems without having to make blind guesses.