Simple noob I/O question (C++) - 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;
}

Related

Reading coordinate file with ifstream while ignoring headers and writing to array

There's a series of coordinates I'm trying to write to an array so I can perform calculations on, but I haven't been able to read the file correctly since I can't ignore the headers, and when I do remove the headers it also doesn't seem to correctly write the values to the array.
The coordinate file is a txt as below.
Coordinates of 4 points
x y z
-0.06325 0.0359793 0.0420873
-0.06275 0.0360343 0.0425949
-0.0645 0.0365101 0.0404362
-0.064 0.0366195 0.0414512
Any help with the code is much appreciated. I've tried using .ignore to skip the two header lines but they don't seem to work as expected.
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
using namespace std;
int main() {
int i = 1;
int count = 1;
char separator;
const int MAX = 10000;
int x[MAX];
int y[MAX];
int z[MAX];
int dist[MAX];
char in_file[16]; // File name string of 16 characters long
char out_file[16];
ifstream in_stream;
ofstream out_stream;
out_stream << setiosflags(ios::left); // Use IO Manipulators to set output to align left
cout << "This program reads a series of values from a given file, saves them into an array and performs calculations." << endl << endl;
// User data input
cout << "Enter the input in_file name: \n";
cin >> in_file;
cout << endl;
in_stream.open(in_file, ios::_Nocreate);
cout << "Enter the output file name: \n";
cin >> out_file;
cout << endl;
out_stream.open(out_file);
// While loop in case in_file does not exist / cannot be opened
while (in_stream.fail()) {
cout << "Error opening '" << in_file << "'\n";
cout << "Enter the input in_file name: ";
cin >> in_file;
in_stream.clear();
in_stream.open(in_file, ios::_Nocreate);
}
while (in_stream.good) {
in_stream.ignore(256, '\n');
in_stream.ignore(256, '\n');
in_stream >> x[i] >> separator >>y[i] >> separator >> z[i];
i++;
count = count + 1;
}
cout << x[1] << y[1] << z[1];
in_stream.close();
out_stream.close();
return 0;
}
Within your reading of the file, you are using in_stream.ignore(256, '\n'); correctly, but you want to use it outside the while loop. When you have it inside the while loop, every time it runs, you will ignore the first two lines, then read the third. Your output would actually read in only a third of what you expect. To fix this, just move those 2 lines outside the while loop.
in_stream.ignore(256, '\n');
in_stream.ignore(256, '\n');
while (in_stream.good)
{
in_stream >> x[i] >> separator >>y[i] >> separator >> z[i];
i++;
count = count + 1;
}
This should fix your problem, but you should generally use a vector instead of an array. Vectors automatically manage memory and check for bounds instead of you having to do that.
Also, good practice is to read values out of the stream as the while condition instead of in_stream.good:
while(stream >> var)
{
//Your code here
}
Here is a good resource on why that is.

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

Input elements differ from output elements from files C++

I have been having some problems with my code. I was asked to input elements from an .dat file into an array. For class we have to do this for various files without knowing how many elements will be in each file. The only thing we know is that here will never be more then 5000 elements per file.
One of my input file has the following elements:
5.675207 -0.571210
0.728926 0.666069
2.290909 0.751731 2.004545 0.907396
0.702893 0.646427 5.909504 -0.365045
2.082645 0.871841 5.597107 -0.633507
6.117769 -0.164663 6.091736 -0.190282
5.571074 -0.653433 4.503719 -0.978307
3.983058 -0.745620
3.670661 -0.504729
5.857438 -0.413001
When I run my code:
#define _CRT_NONSTDC_NO_DEPRECATE
#include <iostream>
#include <fstream>
#include <cstring>
using namespace std;
int main(int argc, char * argv[])
{
ifstream fin;
ofstream fout;
if (argc < 3)
{
cout << "Incorrect usage: prog.exe filenname number" << endl;
cout << "Exiting now, please try again." << endl;
return -1;
}
fin.open(argv[1]);
if (!fin)
{
cout << "Error opening file \"" << argv[1] << "\", exiting." << endl;
return -1;
}
fout.open(argv[2]);
int count = 0;
int word;
double points[5000];
while (fin >> word)
{
fin >> points[count];
++count;
}
fout << "Numer of points is: " << count/2 << endl;
for (int i = 0; i < count; i++)
{
fout << points[i] << " ";
}
fin.close();
fout.close();
return 0;
}
I outputted the elements just to make sure that they were properly inputted. I get the following and I don't know why.
0.675207 0.57121
0.728926 0.666069
0.290909 0.751731 0.004545 0.907396
0.702893 0.646427 0.909504 0.365045
0.082645 0.871841 0.597107 0.633507
0.117769 0.164663 0.091736 0.190282
0.571074 0.653433 0.503719 0.978307
0.983058 0.74562
0.670661 0.504729
0.857438 0.413001
The first digit is converted to a 0 for some reason and the negative ones become positive. Would anyone know why this is occurring?
int word;
is doing you no favours. First it's an integer so fin >> word only reads the integer portion of the inputs. 5.675207 is read as 5. the .675207 is left in the file stream for fin >> points[count]. Words isn't stored anywhere to the 5 is discarded but the .675207 lives on as 0.675207 in points[0].
Where the negative signs are going I didn't bother trying to figure out because
while (fin >> points[count])
{
++count;
}
fixes everything.
When you read in the numbers from the the file you are extracting them as "word" and then storing them as "points". "word" is an integer and "points" is a double, this will give you unexpected behavior. The compiler should give you warnings about this.

Using ifstream to print integers from text files

I have an assignment where I am supposed to read multiple files containing integers (one on each line) and merge them into a output text file after sorting them. I am new to C++ so I do not know how everything works. I am testing my program with two .txt files. The first file is called fileone.txt, contains 1,2,7 (I do not know how to format this but they are all on different lines.) The second file is called filetwo.txt, and contains 1,3,5,9,10 (again every integer is on a different line).
I have written the following code which opens both files and prints the contents.
#include <iostream>
#include <fstream>
using namespace std;
int main(int argc, char** argv) {
ifstream iFile;
ifstream jFile;
iFile.open("fileone.txt");
jFile.open("filetwo.txt");
int int1 = 0;
int int2 = 0;
if (iFile.is_open() && jFile.is_open() ){
while (iFile.good() || jFile.good() ) {
iFile >> int1;
jFile >> int2;
cout << "From first file:" << int1 << endl;
cout << "From second file:" << int2 << endl;
}
}
iFile.close();
jFile.close();
return 0;
}
The output of this program is
The problem I am having is the last number in the first file gets printed multiple times. The output I want is to stop printing after printing the last integer from the file. The problem only appears when the second file contains more integers than the first one. Is there a way to stop printing from the first file when it reaches the end and while still print all the numbers from the second file?
This will do the trick
while (iFile || jFile) {
if(iFile >> int1) // make sure the read succeeded!!
cout << "From first file:" << int1 << endl;
if(jFile >> int2) // make sure the read succeeded!!
cout << "From second file:" << int2 << endl;
}
You should only really use data if you checked to see if it was successfully read.
Consider changing the while loop as follow
while (iFile.good() || jFile.good() ) {
iFile >> int1;
jFile >> int2;
int c = iFile.peek();
int d = jFile.peek();
if (c == EOF) {
if (!iFile.eof())
cout << "From first file:" << int1 << endl;
}
if (d == EOF) {
if (!jFile.eof())
cout << "From second file:" << int2 << endl;
}
}
The thing is to check the end of file and handle if to print it. You can use eof() function as above.
I haven't checked the code. But the logic should be correct.

Read from file (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.