Read from file (C++) - c++

I can't figure out why this won't read from my file...
#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
using namespace std;
int main()
{
int acctNum;
int checks;
double interest;
double acctBal;
double monthlyFee;
const int COL_SZ = 3;
ifstream fileIn;
fileIn.open("BankAccounts.txt");
if(fileIn.fail())
{
cout << "File couldn't open." << endl;
}
else
{
cout << left;
cout << "Bank Account records:" << endl;
cout << setw(COL_SZ) << "Account#" << setw(COL_SZ) <<
"Balance" << setw(COL_SZ) << "Interest" << setw(COL_SZ) << "Monthly Fee" << setw(COL_SZ) <<
"Allowed Checks" << setw(COL_SZ) << endl;
while(fileIn >> acctNum >> acctBal >> interest >> monthlyFee >> checks)
{
cout << setw(COL_SZ) << acctNum << setw(COL_SZ) << acctBal << setw(COL_SZ) << interest << setw(COL_SZ) <<
monthlyFee << setw(COL_SZ) << checks << endl;
}
}
fileIn.close();
system("pause");
return 0;
}
I took out the ios::out and put in ios::in same thing happened no data and the same thing with taking ios out all together. I did make the file from a previous program...would i have to put the reading of the files code into that program?

Edit
Looking at your input you can't read such complex input with just
while(fileIn >> acctNum >> acctBal >> monthlyFee >> checks)
This code is setup to read data formatted in the following form:
11 12.12 11.11 13.13 14.12
11 12.12 11.11 13.13 14.12
11 12.12 11.11 13.13 14.12
Instead you'll have to read the various strings and such before scraping out the data you need. For example to skip over the word "Account" below, you can read it into a dummy string
Account Number#1234
std::string dummy;
fileIn >> dummy; // read up to the whitespace,
// in this case reads in the word "Account"
Then To get the number you'll have to read the next string and extract the #1234
std::string temp;
fileIn >> temp; // read up to the whitespace,
// in this case reads in the word "Number#1234"
But you could also use getline to read up to and including the #
std::getline(fileIn, dummy, '#');
Then read in the number after the #
int acctNum = 0;
fileIn >> acctNum;
So if you're input is truly formatted as you describe, you'll have to spend a lot more time figuring out how to parse your data then you may have expected. I don't know enough about how your input is expected to give you a complete answer, but the above should hopefully get you started.
(Optionally, you could learn about regular expressions, but at this point you may just want to learn the basics.)
Original
I just tried your code out and with enough well-formatted values in the input, it works in g++. However, one thing that I am wary of looking at your code is this line:
while(fileIn >> acctNum >> acctBal >> monthlyFee >> checks)
If any of the above fails to read due to the file ending prematurely, your cout isn't going to get executed, causing no output to the screen. Does your input have all the above values? Are they well formatted? To debug I might try breaking up the reads:
while (fileIn)
{
fileIn >> acctNum;
std::cout << "Acct num is:" << acctNum << std::endl;
...
}
or just step through with a debugger.
For example for this input:
11 12.12 11.11 13.13 14.12
your code prints out
Bank Account records:
Account#BalanceInterestMonthly FeeAllowed Checks
11 12.126.93517e-31011.1113 `
But screwing with the input and adding a random non numeric character somewhere, ie:
11 * 12.12 11.11 13.13 14.12
causes me to get just
Bank Account records:
Account#BalanceInterestMonthly FeeAllowed Checks
So I would definitely look piece-by-piece at what's getting read and where a read from fileIn is failing, this would definitely cause your problems.
You know of course to remove the ios::out as specified here

You have
fileIn.open("BankAccounts.txt", ios::out);
^^^^^^^^
You're opening the file for output. Try ios::in.

Related

ifstream doesn't seem to open an external exe for reading and writing

I am a beginner hobby programmer.
I am working on a small program that will take the FEN string of any chess position from the user, pass it into the Stockfish chess engine, and grab a move output from the exe once it has done its magic in finding a move.
The problem is, once I enter the FEN string into my compiled program, the command line window remains static, and outputs nothing. When I press enter, new lines simply appear, and when I enter anything other than spaces, the command line window closes.
I tried opening Task manager to check to see if Stockfish was running after the FEN string was entered, and I couldn't find it anywhere, which must mean Stockfish wasn't opened by my program to begin with.
The following code has been compiled with g++ in Windows smoothly with no error messages to be found.
After doing some research online, I have tried changing "Stockfish.exe" to "C:....(path)..\Stockfish.exe" to no avail (with loads of compilation errors too).
Am I missing something? What must I do in order for the program to actually open Stockfish and enter the FEN and UCI commands?
Many thanks!
^_^
#include <iostream>
#include <fstream>
#include <cctype>
#include <string>
using namespace std;
int main() {
cout << "Welcome to the Chess Puzzle Solver 1.0!" << endl;
cout << "Please enter the FEN string of the position you'd like to solve." << endl;
cout << "" << endl;
cout << "Example: rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1" << endl;
cout << "[The starting position] ^" << endl;
cout << "" << endl;
string userStartingFEN;
cin >> userStartingFEN;
// Opening Stockfish to do the main stuff!
ifstream inFile;
ofstream outFile;
inFile.open("Stockfish.exe", ios::in | ios::out);
outFile.open("Stockfish.exe", ios::in | ios::out);
string uciCommand1;
uciCommand1 = "uci";
string uciCommand2;
uciCommand2 = "setoption name Threads value 4";
string uciCommand3;
uciCommand3 = "setoption name Contempt value 0";
string uciCommand4;
uciCommand4 = "setoption name Hash value 64";
cin >> uciCommand1;
cin >> uciCommand2;
cin >> uciCommand3;
cin >> uciCommand4;
cout << "I will say this if the parameters were set." << endl;
// Entering the user's wanted position
string inputtingFEN;
inputtingFEN = "position fen ";
cin >> inputtingFEN >> userStartingFEN;
string checkMe;
checkMe = "UCI and Position all set!";
cout << checkMe << endl;
inFile.close();
outFile.close();
return 0;
}

C++: Reading in from a file and displaying individual items

So I have a .txt file I'm supposed to be reading information in from and displaying in a neat little table. Here's a snippet of the .txt files contents
in the format
Farm name, item count, item, price, total price
Collins Farm, 43900 tomatoes 0.67 29413
Bart Smith Farms, 34910 cassavas 0.99 34560.9
Allen Farms, 117 coconuts 0.54 63.18
etc...
It should print out in the console as
Collins Farm (some spaces here) 43900 items contributed totaling $29413.00
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
using namespace std;
int addLine(int);
int main()
{
using std::ifstream;
ifstream myFile;
myFile.open("ASSGN6-B.txt");
string farmName;
int itemCount;
string itemName;
double itemPrice;
double totalPrice;
if (!myFile)
{
cout << "File open failed!" << endl;
}
else
{
cout << "\t\t\t=========================================================" << endl;
cout << "\t\t\t= FARMER'S MARKET INVENTORY =" << endl;
cout << "\t\t\t=========================================================" << endl;
while (myFile.good())
{
getline (myFile, farmName);
getline (myFile, itemName);
myFile >> itemName >> itemPrice >> totalPrice;
cout << farmName << " " << itemCount << " items contributed totaling $" << totalPrice << endl;
}
}
myFile.close();
return 0;
}
This is what I've been messing with trying to figure out how this input stuff works. I guess what I really don't get is how it's supposed to know which item is which. I previously thought it just read in a line at a time only but theres's gotta be a way to separate the items even on the same line and print them all separately in the console.
Also, some farm names appear twice in the .txt file and I'm supposed to combine their data into one line if it's a duplicate. Help with this would be appreciated too.
Thanks.
First piece of advice:
Don't use
while (myFile.good()) { ... }
You need to make sure that the data you expect to read are indeed read successfully.
See Why is iostream::eof inside a loop condition considered wrong? to understand why.
Coming to the other problems...
The line
getline (myFile, farmName);
will read an entire line to farmName. That's not what you want. You want to read everything up to the comma (,) character. std::getline has such an option. Use
getline (myFile, farmName, ',');
It's not clear what you were hoping to accomplish by
getline (myFile, itemName);
That line can be removed.
Looking at the sample data, all you need is
myFile >> itemCount >> itemName >> itemPrice >> totalPrice;
to read rest of the data.
However, after you read them, make sure to ignore the everything in that line. You can use istream::ignore for that.
Here's my suggestion.
while ( getline(myFile, farmName, ',') &&
(myFile >> itemCount >> itemName >> itemPrice >> totalPrice) )
{
cout << farmName << " " << itemCount << " items contributed totaling $" << totalPrice << endl;
// Ignore rest of the line
myFile.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
Make sure to add
#include <limits>
to be able to use std::numeric_limits.
I think you should try to do more research to understand file operations in c++, but I noticed a few things with your code:
getline(myFile, farmName);
This line will take the entire line of the file it's reading and store it into farmName. It basically reads the line until it finds the end of line character. I think your intention was for the line to read until the comma for the farm name, thus you would use:
getline(myFile, farmName, ',');
The third parameter is an optional delimiting character that tells getline what character to look for to stop reading at.
The next lines that I noticed are:
getline(myFile, itemName);
myFile >> itemName >> itemPrice >> totalPrice;
Why are you reading data into itemName twice? I think you meant to read into itemCount first before itemName by the looks of your file format, thus you should eliminate the first line shown above and just have:
myFile >> itemCount >> itemName >> itemPrice >> totalPrice;
In terms of adding to the existing data if the farm name appears more than once, your current code overwrites the data from each line after printing and continuing to the next iteration of the while loop. Thus, you would have to redesign your code to save previous values from farms and check if the farm appears more than once and determine what to do from there.
Could use regex:
std::string line;
std::regex r{R"(([^,]*), ?([^ ]*) ([^ ]*) ([^ ]*) (\d*.?\d*))"};
std::smatch m;
while(getline(myFile, line)){
std::regex_match(line, m, r);
std::string farmName { m[1] };
int itemCount {std::stoi(m[2])};
std::string itemName { m[3] };
double itemPrice {std::stod(m[4])};
double totalPrice {std::stod(m[5])};
std::cout << farmName << " " << itemCount << " items contributed totaling $" << totalPrice << std::endl;
}

Homework Assignment infile / outfiles

My assignment states the following :
Three employees in a company are up for a special pay increase. You are given a file, Ch3_Ex7Data.txt, with the following data:
Miller Andrew 65789.87 5
Green Sheila 75892.56 6
Sethi Amit 74900.50 6.1
Each input line consists of an employee's last name, first name, current salary, and percent pay increase.
For example, in the first input line, the last name of the employee is Miller, the first name is Andrew, the current salary is 65789.87, and the pay increase is 5 %.
Write a program that reads data from the specified file and stores the output in the file Ch3_Ex7Output.dat. For each employee, the data must be output in the following form: firstName lastName updatedSalary Format the output of decimal numbers to two decimal places.
My code is the following.
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
using namespace std;
int main()
{
//Declaring the variables
string firstName;
string lastName;
double payIncrease;
double pay;
ifstream inFile;
ofstream outFile;
inFile.open("C:\\Users\\Megan\\Ch3_Ex7Data.txt"); //opens the input file
outFile.open("C:\\Users\\Megan\\Ch3_Ex7Output.dat"); //opens a output file
outFile << fixed << showpoint;
outFile << setprecision(2); // Output file only having two decimal places
cout << "Processing Data....." endl; //program message
while (!inFile.eof() //loop
inFile >> lastName >> firstName >> pay >> payIncrease;
pay = pay*(pay*payIncrease);
outFile << firstName << " " << lastName << " " << pay << "/n";
inFile.close();
outFile.close();
return 0;
}
For some reason I cannot seem to get the code to open my existing .txt file, read it and then translate it to another file. Does anybody see anything wrong with this that could help me out?
You have many problems with you code.
The two most evident prevent the program from compiling:
cout << "Processing Data....." endl; //program message
should be:
cout << "Processing Data....." << endl; //program message
and while (!inFile.eof() //loop should be at least while (!inFile.eof() )//loop
That's not all:
while (!inFile.eof()) is an anti-idiom: you test for end of file, then read and do the processing even if an error or end of file has occured. You must test after reading.
And as you were said in comment, without { } only the first line after the while is repeated, which is not what you want.
The correct formula to add a percent increase is pay = pay*(1 + payIncrease/100.); at least pay = pay+(pay*payIncrease/100.);
Adding a '/n' as an end of line is plain wrong. The character is '\n' (note the backslash), and anyway you should always write endl in C++.
Once all that is fixed, the loop becomes:
for (;;) { //loop
inFile >> lastName >> firstName >> pay >> payIncrease;
if (! inFile) break; // exit on eof or error
pay = pay*(1 + payIncrease/100.);
outFile << firstName << " " << lastName << " " << pay << endl;
}
and the output is:
Andrew Miller 69079.36
Sheila Green 80446.11
Amit Sethi 79469.43
But is you want to learn good pratices, you should also:
test the opening of both files
test after end of loop if the termination was caused by an error and issue a warning
last by not least learn to use a debugger...
This was my solution
#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;
int main() {
// Write your main here
//Declarations
string FirstName;
string LastName;
double Pay;
double Increase;
double UpdatedSalery;
//File object and open txt and dat files per instructions and use user input for the txt input file
ifstream FileIn;
string FileName;
cout << "enter a file name: ";
cin >> FileName;
FileIn.open(FileName);
ofstream FileOut("Ch3_Ex5Output.dat");
FileOut << setprecision(8);
while(FileIn >> LastName >> FirstName >> Pay >> Increase){
UpdatedSalery = ((Pay*(Increase/100))+Pay);
FileOut << " " << FirstName << " " << LastName << " " << UpdatedSalery << endl;
}
FileIn.close();
FileOut.close();
return 0;
}

C++ file writing - not writing variables as expected

I've looked through a few different things (cant seem to find a good file i/o tutorial on pluralrsight), and I've read tutorialspoint and cplusplus websites on file writing but mine won't seem to work the same.
I copied rather similarly, the tutorial fro tutorialspoint on C++ file I/O:
ofstream out;
out.open("D:\\cpp_files\\test_iofile.txt", ios::out);
cout << "Writing to file" << endl;
cout << "Enter your name: ";
string name;
getline(cin, name);
out << name;
cout << "Enter age: ";
int age;
cin >> age;
out << age << endl << "This is an insert" << endl;
out.close();
There's some more stuff in the middle you probably don't care much about, and then there's this section:
out.open("D:\\cpp_files\\test_iofile.txt", ios::ate);
out << endl;
string inp;
cout << "Write some random crap: ";
getline(cin, inp);
out << inp << endl;
out << "-----------";
out.close();
The weird thing is, it creates the .txt file in the right location, but its output equates to 2 blank lines and the dashes. So I end up with (The '>' added to indicate blank lines):
>
>
----------
I know it must be something I am missing, but I can't seem to catch it. No build errors from the compiler either.
You have to flush the buffer after you cin >> age;,
cin.ignore (std::numeric_limits<std::streamsize>::max(), '\n');
and change ios::ate to ios::app
must #include <limits>
ios:ate truncates the file, whereas ios::app appends at the end.
An alternative to cin.ignore is to use after cin >> age the getline as
getline(cin >> ws, inp);
This instructs the input stream to discard previously accumulated "whitespaces", i.e. newline, tabs etc

Simple noob I/O question (C++)

sorry for the noob question, but I'm new to C++.
I need to read some information, line-by-line, from a file, and perform some calculations, and output into another file. For example, we read a unique ID for each line, a name, and 2 numbers. The last 2 numbers are multiplied, and in the output file, the ID, name and product are printed line by line:
input.txt:
2431 John Doe 2000 5
9856 Jane Doe 1800 2
4029 Jack Siu 3000 10
output.txt:
ID Name Total
2431 John Doe 10000
9856 Jane Doe 3600
4029 Jack Siu 30000
My code is similar to this, but only the first line appears in the output file. If I press Enter repeatedly, the other lines appear in the output file:
#include <fstream>
using namespace std;
ifstream cin("input.txt");
ofstream cout("output.txt");
int main () {
int ID, I, J;
string First, Last;
char c;
cout << "ID\tName\t\Total\n";
while ((c = getchar()) != EOF) {
cin >> ID >> First >> Last >> I >> J;
cout << ID << " " << First << " " << Last << " " I * J << "\n";
}
return 0;
}
That's my only problem, that the values don't appear in the output file, unless I press Enter repeatedly, then close the program. Can anyone suggest a fix for my code above, to have it do the task without keyboard input? Thanks!
Use
while (!cin.eof()) {
using namespace std;
ifstream cin("input.txt");
ofstream cout("output.txt");
You've hidden the real std::cin and std::cout...and will later read from them.
while ((c = getchar()) != EOF) {
But here you use the real std::cin to check for EOF.
The getchar() call reads waits for you to type a character (and press Enter) since it reads from stdin (standard input). Try changing the loop condition to stop reading when cin reaches end of file.
EDIT
You should also use different names for input and output streams -- there are already cin and cout in the std namespace.
This is because you used getchar() in your while loop condition. Not sure what you were trying to do, but getchar() reads a char from stdin. What you should have done, is check if cin failed or encountered EOF.
While I was looking for the answer I though I better check and make sure it worked. I got some build errors and got a little carried away from there.
Hope this helps!
#include <iostream>
#include <fstream>
using namespace std;
int main () {
ifstream indata("input.txt");
if(!indata)
{ // file couldn't be opened
cerr << "Error: input.txt could not be opened" << endl;
exit(1);
}
ofstream output("output.txt");
if(!output)
{ // file couldn't be opened
cerr << "Error: output.txt could not be opened" << endl;
exit(1);
}
int ID, I, J;
char First[10], Last[10];
output << "ID\tName\tTotal\n";
while (!indata.eof())
{
indata >> ID >> First >> Last >> I >> J;
output << ID << " " << First << " " << Last << " " << I * J << endl;
}
indata.close();
output.close();
return 0;
}