Assistance with file input and output in C++ - c++

First of all, Thank you for the help and I hope I'm following your guidelines correctly, if I'm not, I'd be more than happy to correct it.
I need some help with an assignment I have. After finally getting it to run, my program won't open the files I need. The program should open a file named prog10in.txt and output it into a file named prog10out.txt However, I put a line in it that would tell me if it failed and that keeps coming up. I am doing this in Visual Studio. I need to understand how to properly open the file whether my error is in the code or in Visual Studio. The program compiles without error.
The error should be in getAccountInfo() or outputFile().
Source.cpp:
#include <iostream>
#include <string>
#include "Account.h"
#include "Bank.h"
#include <cstdio>
#include <fstream>
#include <iomanip>
using namespace std;
ifstream inStream;
int main(int argc, char* argv[])
{
Account accounts[MAXIMUM_ACCOUNTS];
Bank Customer;
int AccountNumber = 0;
int ID;
string lastName;
string firstName;
double balance;
Customer.getAccountInfo(argv, AccountNumber, ID, lastName, firstName,balance, accounts);
Customer.sort(AccountNumber, accounts);
Customer.outputFile(argv, AccountNumber, accounts);
}
There is an Account.h and Account.cpp file that holds the account information class.
Bank.cpp:
#include <iostream>
#include <string>
#include "Account.h"
#include "Bank.h"
#include <cstdio>
#include <fstream>
#include <iomanip>
void Bank::getAccountInfo(char* argv[], int& accountNumber, int& accountID, std::string& accountLastName, std::string& accountFirstName, double& accountBalance, Account Customers[MAXIMUM_ACCOUNTS])
{
std::ifstream fin;
int accountIndex = 0;
fin.open(argv[1]);
if (fin.fail())
{
std::cout << "Input file did not open" << std::endl;
system("pause");
exit(1);
}
while (!fin.eof() && accountIndex < MAXIMUM_ACCOUNTS)
{
std::cout.setf(std::ios::fixed | std::ios::showpoint | std::ios::right);
std::cout.precision(2);
fin >> accountID >> accountLastName >> accountFirstName >> accountBalance;
fin.ignore(1, ' ');
Customers[accountIndex]._accountID = accountID;
Customers[accountIndex]._accountLastName = accountLastName;
Customers[accountIndex]._accountFirstName = accountFirstName;
Customers[accountIndex]._accountBalance = accountBalance;
accountIndex++;
accountNumber++;
}
std::cout << "Clients: " << accountIndex << std::endl;
}
void Bank::sort(int accountNumber, Account Customers[MAXIMUM_ACCOUNTS])
{
int nextSmallest;
int IDtemp;
std::string lastNameTemp;
std::string firstNameTemp;
double balanceTemp;
for (int accountIndex = 0; accountIndex < accountNumber; accountIndex++)
{
nextSmallest = accountIndex;
for (int accountIndex2 = accountIndex + 1; accountIndex2 < accountNumber; accountIndex2++)
{
if (Customers[accountIndex2]._accountID < Customers[nextSmallest]._accountID)
{
nextSmallest = accountIndex2;
}
IDtemp = Customers[accountIndex]._accountID;
Customers[accountIndex]._accountID = Customers[nextSmallest]._accountID;
Customers[nextSmallest]._accountID = IDtemp;
lastNameTemp = Customers[accountIndex]._accountLastName;
Customers[accountIndex]._accountLastName = Customers[nextSmallest]._accountLastName;
Customers[nextSmallest]._accountLastName = lastNameTemp;
firstNameTemp = Customers[accountIndex]._accountFirstName;
Customers[accountIndex]._accountFirstName = Customers[nextSmallest]._accountFirstName;
Customers[nextSmallest]._accountFirstName = firstNameTemp;
balanceTemp = Customers[accountIndex]._accountBalance;
Customers[accountIndex]._accountBalance = Customers[nextSmallest]._accountBalance;
Customers[nextSmallest]._accountBalance = balanceTemp;
}
}
}
void Bank::outputFile(char* argv[], int accountNumber, Account Customers[MAXIMUM_ACCOUNTS])
{
int outFileIndex;
std::ofstream fout;
fout.open(argv[2]);
if (fout.fail())
{
std::cout << "Output file did not open" << std::endl;
system("pause");
exit(1);
}
if (fout.fail())
{
std::cout << "Output failed" << std::endl;
exit(0);
}
fout.setf(std::ios::fixed | std::ios::showpoint | std::ios::right);
fout.precision(2);
for (outFileIndex = 0; outFileIndex < accountNumber; outFileIndex++)
{
fout << std::setw(6) << Customers[outFileIndex]._accountID;
fout << std::setw(10) << Customers[outFileIndex]._accountLastName;
fout << std::setw(10) << Customers[outFileIndex]._accountFirstName;
fout << std::setw(10) << Customers[outFileIndex]._accountBalance;
fout << std::setw(10) << std::endl;
}
}
Again, thank you guys for the help.

I think your program don't find the input file. right? because the output file will be created if not exists.
So about the input, if you use an absolute path it should work unless the path is wrong. but if you are using a relative path. you should know that running the program from visual studio the current directory (.) will be the projects directory.

Your path is not correct. if filename is "abc.txt" and the file is present in same folder as that of binary (exe file) than you only need to provide the name. If not than provide the full path of the file in double quotes (if space is present)

Related

Cross referencing data from file

Cant figure this out....I got two txt files, one is encoding1.txt which contains a set of hexadecimals and the ID number that is assigned to them, such as
61 1
C3A4 2
C990 4
C991 5
C991CC83 6
C992 7
CA8C 9
The other file source.txt is the source file which contains a bunch of combined hex and the students' names
CA8CC992 Jack
C991C3A4 Amy
C991CC83 Sam
61C991 Tom
I want to output a txt file for each students with their name as their filenames and inside the file should be the assigned numbers of their hex. e.g. for jack.txt, inside it should be
9
7
Below is the code that I've tried it generates all the test file but inside its jack.txt theres only 9 and other files are empty. Whats the correct way to do this and how do I get the results right?
#include "stdafx.h"
#include <iostream>
#include <string>
//#include<map>
//#include<unordered_map>
#include <fstream>
#include<array>
//#include<vector>
#include <algorithm>
using namespace std;
int main()
{
std::ifstream file;
file.open("encoding1.txt");
if (file.is_open())
{
std::cout << "opened encoding1 file";
}
std::ifstream file2;
file2.open("source.txt");
if (file.is_open())
{
std::cout << "opened source file" << std::endl;
}
std::ofstream outfile;
const int hexencosize = 7;
std::string hexenco[hexencosize] = {};
int id[7] = {};
std::string hexsource;
string * p;
std::string name;
for (int i = 0; i < 6; i++)
while (file >> hexenco[i] >> id[i]) {
std::cout << "hexenco is " << hexenco[i] << std::endl;
std::cout << "id is " << id[i] << std::endl;
};
for (int o = 0; o < 6; o++)
while (file2 >> hexsource >> name) {
outfile.open(name + ".txt");
std::size_t found = hexsource.find(hexenco[o]);
if (found != std::string::npos)
p = std::find(hexenco, hexenco + hexencosize, hexenco[o]);
if (p >= hexenco + hexencosize) std::cout << "Not found" <<
std::endl;
else outfile << id[p - hexenco] << '\n';
outfile.close();
};
system("pause");
return 0;
};

Reading a File's Line with no Spaces into separate Variables

First time asking a question on this site, so here goes. I've been racking my brain for quite some time, but still can't seem to find the answer to this.
Let's say I have a file that reads as follows:
123456789John Doe 0001111.11
925219042Mary Jane 0000302.54
891492829Gertrude Marisou 0123467.76
How would I separate say, 123456789 and John into their own respective strings for input into a vector containing four variables? (Std::string, Std::string, Std::string, Double)
Here is my current code if you all would like to take a peek at it and tell me where I am going wrong.
#pragma once
#if !defined(__Account7_h__)
#define __Accoun7_h__
#include <string>
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <sstream>
//Personal file for trimming the extra whitespace
#include "Trim.h"
class Account7 {
private:
std::string account_code;
std::string first_name;
std::string last_name;
double balance;
public:
//Getters, Setters, Initialization List and whatnot.
//On a separate file
#if !defined(__Vmanager7_h__)
#define __Vmanager7_h__
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <sstream>
#include "Account7.h"
#include "Trim.h"
using namespace generic;
class Vmanager7 {
public:
int a = 1;
std::ifstream infile;
std::ofstream outputFile;
std::vector<Account7> _Account;
Account7 temp;
std::string Empl;
std::string scapeg;
std::string acc_c;
std::string fname;
std::string lname;
double bal;
int Managed() {
int count;
infile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
try {
infile.open("account.dat", std::ifstream::in);
}
catch (std::ios_base::failure &fail) {
std::cout << "File is not opening" << std::endl;
return 0;
}
infile.exceptions(std::ios::goodbit);
while (getline(infile, Empl)) {
count = 1;
std::istringstream ss(Empl);
while (getline(ss, scapeg)) {
if (count == 1)
acc_c = scapeg;
else if (count == 2)
fname = scapeg;
else if (count == 3)
lname = scapeg;
else
bal = atof(scapeg.c_str());
count++;
}
temp.setac(acc_c);
temp.setfn(fname);
temp.setln(lname);
temp.setba(bal);
_Account.push_back(temp);
}
infile.close();
outputFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
try {
outputFile.open("Aoutput.dat");
}
catch (std::ios_base::failure &fail) {
std::cout << "File opening fail" << std::endl;
return 0;
}
outputFile.exceptions(std::ios::goodbit);
for (int i = 0; i < _Account.size(); i++) {
std::cout << _Account[i].getac() << " " << _Account[i].getfn() << " " << _Account[i].getln() << " " << _Account[i].getba();
bal = _Account[i].getba();
bal -= int(bal);
if (bal == 0)
std::cout << ".00";
std::cout << '\n';
}
outputFile.close();
}
};
};
The output I get is something along the lines of this:
123456789John Doe 0001111.11 -9.25596e+61
925219042Mary Jane 0000302.54 -9.25596e+61
191492829Gertrude Marisou 0123467.76 -9.25596e+61
I would like the output to look just like the input. Any help would be immensely appreciated.

Writing a C++ Program to Search an Index File From the Linux Command Line

I've written a program that reads in a data file and creates a sorted index file from the data in the original file. However, I"m then supposed to write a second program that allows teh user to search this index file from the Linux command line. For example, they are supposed to be able to type
search 12382 prog5.idx
into the command line and have the information for that record displayed. I have no idea how to accomplish this.
I have written the code to create the index file (works):
#include <iostream>
#include <fstream>
#include <map>
#include <sstream>
#include <string>
#include <iomanip>
using namespace std;
class Record {
string name;
int code;
double cost;
public:
Record() {
}
Record(string tname,int tcode,double tcost) : name(tname),code(tcode),cost(tcost) {
}
friend ostream& operator<< (ostream &os, const Record& r);
};
//print function
ostream& operator<< (ostream &os, const Record& r) {
os << setw(10) << r.name << " " << setw(5) << r.code << " $" << setw(10) << setprecision(2) << fixed << r.cost ;
return os;
}
int main() {
std::map<int, Record> myMap;
ifstream data;
size_t offset_count = 0;
data.open("prog5.dat");
ofstream outFile("prog5.idx", ios::out);
//if file can't be opened, exit
if(!data) {
cerr << "Open Failure" << endl;
exit(1);
}
std::string line;
while (std::getline(data, line)) {
stringstream ss(line);
int key;
string name;
int code;
double cost;
if(ss >> key >> name >> code >> cost) {
Record r(name,code,cost);
myMap.insert( pair<int,Record>(key,r));
}
else {
cout << "Error";
}
}
// print what's stored in map
for(std::map<int,Record>::iterator x = myMap.begin(); x!=myMap.end(); ++x) {
cout << setw(10) << x->first << ": " << x->second << endl;
}
}
And get the following output when running the above code:
8: blank 0 $ 0.00
12165: Item16 30 $ 7.69
12345: Item06 45 $ 14.20
12382: Item09 62 $ 41.37
12434: Item04 21 $ 17.30
16541: Item12 21 $ 9.99
21212: Itme31 19 $ 8.35
34186: Item25 18 $ 17.75
41742: Item14 55 $ 12.36
Here's what I have so far for the second program:
#include <prog3.idx>
#include <iostream>
#include <fstream>
using namespace std;
int main(int argc, char** argv) {
if(argc < 3) {
std::cerr << "Too few arguments \n";
std::exit(EXIT_FAILURE);
}
int key = atoi(argv[1]);
const char* filename = argv[2];
ifstream input;
input.open("prog5.idx");
}
But I'm not sure where to go from there. Can someone help me out?
Use map or multimap and find in the STL. Make a datatype out of the remaining data with the index as the key. The program will have to read in the entire file first and then find the searched index.

creating files, checking if another one with the same name exists

Code(main.cpp) (C++):
#include <string>
#include <sstream>
#include <stdio.h>
#include <stdlib.h>
#include <ctime>
//general vars
std::ofstream ofs;
std::ifstream ifs;
std::stringstream ss;
//spamFiles vars
std::string defPath;
int defAmt;
void spamFiles(std::string paramPath);
int main(int argc, const char * argv[])
{
srand(time_t(NULL));
std::cout << "Enter the amount of files: ";
std::cin >> ::defAmt;
std::cout << "Now enter the target path: ";
std::cin >> ::defPath;
::spamFiles(::defPath);
std::cout << defAmt << " files were created." << std::endl;
return 0;
}
void spamFiles (std::string paramPath){
//system("open -a Terminal .");
for(int i = 0; i < ::defAmt; i++){
std::string tempS;
int ranNum = rand() % 501;
ss << ranNum;
std::string ssResult = ss.str();
std::string finalPath = ::defPath + ssResult + ".txt";
ifs.open(finalPath);
if(ifs.good()){
finalPath += "dupe.txt";
while(ifs.good()){
finalPath += "dupe.txt";
ifs.open(finalPath);
}
}
ofs.open(finalPath);
ofs << "";
ofs.close();
ss.str(std::string());
}
return;
}
My problem is following.
Whenever I run this and enter, lets say 53 as for the amount, in the end it'll never create the full amount of files. It's always scaled.
Here's an example.
Defined Amont: 300 -> What I Get: 240
Defined Amount: 20 -> What I get: 15
Defined Amount: 600 -> What I get: 450
Thanks in advance.
Based on the logic of your code, you are creating a file if your ifstream object is not 'good()'. If some files aren't being created, then the error lies here.
With some digging, you'll find that the constructor for an ifstream object does not take a string, but instead a char *.
Adding a c_str() to your 'finalPath' variable should take care of this issue.
Some things to note:
You've forgotten to include fstream and iostream.
When digging into problems like this, don't use random numbers as your first test case. It was easier for me to replicate your issue by just trying to create files in numerical order.
Also don't forget 'close()' your ifstreams!
My adaptation of the code:
#include <string>
#include <sstream>
#include <stdio.h>
#include <stdlib.h>
#include <ctime>
#include <fstream>
#include <iostream>
//general vars
std::ofstream ofs;
std::ifstream ifs;
std::stringstream ss;
//spamFiles vars
std::string defPath;
int defAmt;
void spamFiles(std::string paramPath);
int main(int argc, const char * argv[])
{
srand(time_t(NULL));
std::cout << "Enter the amount of files: ";
std::cin >> ::defAmt;
std::cout << "Now enter the target path: ";
std::cin >> ::defPath;
::spamFiles(::defPath);
std::cout << defAmt << " files were created." << std::endl;
return 0;
}
void spamFiles (std::string paramPath){
//system("open -a Terminal .");
for(int i = 0; i < ::defAmt; i++){
std::string tempS;
int ranNum = rand() % 501;
ss << ranNum;
std::string ssResult = ss.str();
std::string finalPath = ::defPath + ssResult + ".txt";
ifs.open(finalPath.c_str());
while(ifs.good()){
finalPath += "dupe.txt";
ifs.open(finalPath.c_str());
}
ifs.close();
std::cout << finalPath << std::endl;
ofs.open(finalPath.c_str());
ofs << "";
ofs.close();
ss.str(std::string());
}
return;
}

Writing timestamps to files

I am working on a wages application. The application should allow the user to transfer an amount from an account (the account being text file "shop" which contains the value 1000).
The user should be able to make as many transfers as they wish without overdrawing the account. Each transaction should also be recorded by a timestamp in a separate file and this is the bit I am struggling with.
Currently with the code I am using the timestamp is created fine in the file "time" except 1040ED48 appears before the time. Does anyone know why this is? Also every time I do a transaction the "time" file gets overwritten with the new timestamp. Is there a way to put each timestamp on a different line in the file in order to stop it from being completley overwritten? Sorry if this wasn't clear.
#include <limits>
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <ctime>
#include <string>
int read_balance(void);
void write_balance(int balance);
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
cout << "How much do you wish to transfer?" << endl;
int amount = 0;
if (std::cin >> amount)
{
std::cout << "Transferred Amount:" << amount << "\n";
int balance = read_balance();
if (amount <= 0)
{
std::cout << "Amount must be positive\n";
}
else if (balance < amount)
{
std::cout << "Insufficient funds\n";
}
else
{
int new_balance = balance - amount;
write_balance(new_balance);
std::cout << "New account balance: " << new_balance << std::endl;
fstream infile;
infile.open("time.txt");
std::time_t result = std::time(nullptr);
std::string timeresult = std::ctime(&result);
infile << std::cout << timeresult << std::endl;
}
}
system("pause");
return 0;
}
int read_balance(void)
{
std::ifstream f;
f.exceptions(std::ios::failbit | std::ios::badbit);
f.open("shop.txt");
int balance;
f >> balance;
f.close();
return balance;
}
void write_balance(int balance)
{
std::ofstream f;
f.exceptions(std::ios::failbit | std::ios::badbit);
f.open("shop.txt");
f << balance;
f.close();
}
If you open a file for writing, you start by deleting that file. If you don't want to delete the file, you need to open the file for appending (using app mode.)
One more thing. You should print the following after checking the error conditions:
std::cout << "Transferred Amount:" << amount << "\n";
int balance = read_balance();
Imagine you are at ATM. Now you try to withdraw more than what you have left in your account and ATM shows that money is transferred and indicates that you don't have enough balance.