File Handling - Value is being added two times instead of one [duplicate] - c++

This question already has answers here:
Reading from text file until EOF repeats last line [duplicate]
(7 answers)
Closed 2 years ago.
When I run my code it is adding the value of 81 two times. Why ???
Write a program to read the contents of file Squares.txt and display the
sum of all the numbers, the average of all the numbers, the largest
number and the smallest number in a file named Analysis.txt.
Content in Squares.txt :
Number Square
3 9
5 25
1 1
7 49
9 81
#include <iostream>
using namespace std ;
#include <fstream>
int main() {
ifstream file ;
char arra[100];
int num1,num2,avg;
int sum=0 ;
int smallest = 9999 ;
int highest = -999 ;
int count= 0 ;
cout<<"Open file square.txt..."<<endl ;
file.open("/Users/kchumun/Documents/Xcode/Labsheet 8(3)/square2.txt") ;
if(!file){
cout<<"File cannot be opened !"<<endl ;
}else {
cout<<"File opened !"<<endl;
file.get(arra,100) ;
while(!file.eof()){
file>>num1;
file>>num2 ;
sum+=num2;
count++ ;
if(num2<smallest){
smallest = num2 ;
}
if (num2>highest) {
highest = num2 ;
}
}
}
file.close() ;
avg= sum / count ;
cout<<"Sum= "<<sum<<endl ;
cout<<"Average= "<<avg<<endl;
cout<<"Highest= "<<highest<<endl ;
cout<<"Smallest= "<<smallest<<endl;
ofstream File ;
cout<<"Open file Analysis "<<endl ;
if(!File){
cout<<"Error !" ;
}else{
File.open("/Users/kchumun/Documents/Xcode/Labsheet 8(3)/Analysis.txt");
File<<"Sum= "<<sum<<endl ;
File<<"Averagem= "<<avg<<endl;
File<<"Highest= "<<highest<<endl ;
File<<"Smallest= "<<smallest<<endl ;
}
File.close();
cout<<"Operation completed !";
return 0;
}

This style of code is incredibly common but also incredibly wrong
while(!file.eof()){
file>>num1;
file>>num2;
Like this instead please
while (file >> num1 >> num2) {
The problem with your code is a misunderstanding of how eof works. Eof tests if you are at the end of the file right? No, wrong. In reality eof tests if your last read failed because you were at the end of file. A subtly different thing, and this difference explains why your loop seems to read the last item twice.
If you do use eof you should use it after reading to test if the last read failed. Not before reading to predict if the next read will fail.

Related

Extra output when writing to file using std::cout

I am trying to read data from a file in.txt, and after some computations, I am writing the output to out.txt
Why is there an extra 7 at the end of out.txt?
Contents of Solution class.
class Solution
{
public:
int findComplement(int num)
{
int powerof2 = 2, temp = num;
/*
get number of bits corresponding to the number, and
find the smallest power of 2 greater than the number.
*/
while (temp >> 1)
{
temp >>= 1;
powerof2 <<= 1;
}
// subtract the number from powerof2 -1
return powerof2 - 1 - num;
}
};
Contents of main function.
Assume all headers are included. findComplement flips bits of a number. For example, The integer 5 is "101" in binary and its complement is "010" which is the integer 2.
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
// helper variables
Solution answer;
int testcase;
// read input file, compute answer, and write to output file
while (std::cin) {
std::cin >> testcase;
std::cout << answer.findComplement(testcase) << "\n";
}
return 0;
}
Contents of in.txt
5
1
1000
120
Contents of out.txt
2
0
23
7
7
The reason there is an extra 7 is that your loop executes one too many times. You need to check std::cin after you've tried to read the input.
As is, you simply repeat the last test case.

C++ Basic While Loop: Unknown Inputs and Value Increment

So I'm trying to write a program that reads unknown inputs from a data file that has a sentinel 0 or I guess an termination point for the loop.
Number of integers per line before 0 (int count).
Number of all integers in data file (int totalcount).
Number of lines in data file (int lines).
Two examples of unknown inputs from a data file:
Example One:
1 2 3 0 4 5 6 7 0
Example Two:
0 9 11 -11
1 1 0 0 2
0
Here is my program (without "count" because that is where my problem lies):
int main()
{
//Declaring variables.
int input, lines, count, totalcount, datafile;
lines = 0;
count = 0;
totalcount = 0;
//Loop runs as long as data file has an integer to take in.
while(cin >> datafile)
{
//If datafile is not 0, loop runs until datafile is 0.
while(datafile != 0)
{
//Counts all integers in the file except 0.
totalcount += 1;
cin >> datafile;
}
//Counts how many lines there are in a data file using sentinel 0 (not "/n").
if(datafile == 0)
lines += 1;
//Outputs.
cout << lines << setw(11) << count << setw(11) << totalcount << endl;
}
return 0;
}
Please do not worry about technicality, efficiency, or anything else besides the logic/concept itself as I'm just trying to find the missing link in my knowledge to complete this assignment.
With that said, my expected outputs are as formatted:
"Line #" "Counts of integers per line" "Total counts of all integers in data file"
Using example one with my current code, I would have outputs (spacing is not exact and '.' is for blanks):
1......0......3
2......0......7
Correct expected outputs:
1......3......3
2......4......7
I would like any hints or explanation of how I can count the integers per line (before sentinel 0) and assign that value to "int count" without the value persisting to the next line.
I'm a student in an introductory C++ class so please show me a basic way of how I may go about this first and then any other advanced options as necessary for future applications.
Code of Conduct Personal Statement:
By participating, you are providing necessary knowledge for assignment completion, not completing the assignment itself. The example used is generated by me intended for concept demonstration purposes and is only a small part of the final assignment.
10/23/2016 9:56PM Update 1:
Currently attempting to use a "temp" variable to substract from "totalcount". I will update my code if attempt is successful.
totalcount is sum of counts. This is my suggestion
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
//Declaring variables.
int input, lines, count, totalcount, datafile;
lines = 0;
count = 0;
totalcount = 0;
//Loop runs as long as data file has an integer to take in.
while(cin >> datafile)
{
// Add count to totalcount and reset count each time reach 0
if (datafile == 0) {
totalcount += count;
lines += 1;
cout << lines << setw(11) << count << setw(11) << totalcount << endl;
count = 0;
}
//otherwise increase count
else {
count++;
}
}
return 0;
}

Output from array is wrong

#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <fstream>
using namespace std;
void make_array(ifstream &num, int (&array)[50]);
int main(){
ifstream file; // variable controlling the file
char filename[100]; /// to handle calling the file name;
int array[50];
cout << "Please enter the name of the file you wish to process:";
cin >> filename;
cout << "\n";
file.open(filename);
if(file.fail()){
cout << "The file failed to open.\n";
exit(1);
}
else{
cout << "File Opened Successfully.\n";
}
make_array(file, array);
file.close();
return(0);
}
void make_array(ifstream &num, int (&array)[50]){
int i = 0; // counter variable
while(!num.eof() && i < 50){
num >> array[i];
i = i + 1;
}
for(i; i>=0; i--){
cout << array[i] << "\n";
}
}
Alright, so this it my code so far. When I output the contents of the array, I get two really large negative numbers before the expected output. For example, if the file had 1 2 3 4 in it, my program is outputting -6438230 -293948 1 2 3 4.
Can somebody please tell me why I am getting these ridiculous values?
Your code outputs the array backwards, and also it increments i twice after it has finished reading all the values. This is why you see two garbage values at the start. I suspect you are misreporting your output and you actually saw -6438230 -293948 4 3 2 1.
You end up with the extra increments because your use of eof() is wrong. This is an amazingly common error for some reason. See here for further info. Write your loop like this instead:
while ( i < 50 && num >> array[i] )
++i;
Now i holds the number of valid items in the list. Assuming you do actually want to output them backwards:
while ( i-- > 0 )
cout << array[i] << "\n";
To output them forwards you'll need two variables (one to store the total number of items in the array, and one to do the iteration)
The check !num.eof() only tells you that the last thing you read was not eof. So, if your file was 1 2 3 4, the check will only kick in after the 5th num>>array[i] call. However, for that i, array[i] will be populated with a meaningless value. The only correct way to deal with eofs is to check for validity on every call to operator>>. In other words, the right condition is simply num>>array[i]. This works by exploiting this conversion to bool since C++11 and to void* pre-C++11.

How to read from a file [duplicate]

This question already has answers here:
Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?
(5 answers)
Closed 9 years ago.
* For those having this problem, it was the problem with my command. Make sure your command to compile and run the program is correct!
I was watching a tutorial on youtube.
I did exactly the same as the op did, and I get a different output.
I am new to c++, and I am using Xcode to run the code.
here is the code: (again, it's not mine, but from a youtube tutorial video)
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
int input[100];
int x = 0;
int fail = 0;
int pass = 0;
fstream textfile;
textfile.open("exam.txt");
while(! textfile.eof()) {
textfile >> input[x];
cout << input[x] << endl;
if(input[x] < 50) {
fail++;
}
else {
pass++;
}
x++;
}
textfile.close();
cout << fail << "students out of " << (fail + pass) << "did not pass the exam." << endl;
return 0;}
It's supposed to print grades.
But this is what I get when I run it on Xcode.
0
0
0
0
0
0
0
0
1606415288
32767
1606415720
32767
1606415720
32767
2003953588
1294056514
104
1
1606415312
32767
25240
1
1606415288
32767
1606415312
32767
25248
1
1606415288
32767
1606415312
32767
1606415720
32767
25264
1
1606415304
32767
1606415720
32767
1606415720
32767
6144
1
1910210376
32767
1606416728
32767
0
0
0
0
0
0
0
0
0
0
1606416544
32767
2003953588
1294056514
1606416544
32767
-1988827167
32767
0
0
1
0
1606416904
32767
0
0
It's only part of the output. It doesn't terminate.
Also, when I try to run it on linux (sshed into school linux machine),
I get this following error:
##?!#8 # #####?88#8###?? ??`?`?? ``?TT#T#DDP?tdPP#P#DDQ?tR?td??`?` /lib64/ld-linux-x86-64.so.2GNUGNU?Yd?`˫sP???*??"b!!?? (E?L?
CyIk? ^Q#y??K#??'?[?
#3P
# `??
#libstdc++.so.6__gmon_start___Jv_RegisterClasses_ZNSt8ios_base4InitD1Ev_ZNSt13basic_fstreamIcSt11char_traitsIcEEC1Ev_ZNSt13basic_fstreamIcSt11char_traitsIcEE5closeEv_ZNSirsERi_ZNSt13basic_fstreamIcSt11char_traitsIcEE4openEPKcSt13_Ios_Openmode__gxx_personality_v0_ZSt4cout_ZNSolsEi_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6__ZNSt13basic_fstreamIcSt11char_traitsIcEED1Ev_ZNSolsEPFRSoS_E_ZNKSt9basic_iosIcSt11char_traitsIcEE3eofEv_ZNSt8ios_base4InitC1Evlibgcc_s.so.1_Unwind_Resumelibc.so.6__stack_chk_fail__cxa_atexit__libc_start_mainGCC_3.0GLIBC_2.4GLIBC_2.2.5CXXABI_1.3GLIBCXX_3.4 P&y
xui ?ӯk?t)??`? ` ` ` ` `( `0 8 ` # ` p60ii
H `
P `
` `h `p `x `? `H??c????H???5? ?%? #?%? h??????%? h??????%? h??????%? h?????%? h?????%? h?????%? h?????%? h?p????%? ?`????%? h ?P????%? h
?#????%? h
?0????%? h
?????%z h?????%r h??????%j h?????1?I??^H??H???PTI???#H??0#H??
#????????H?H?? H??t??H?Ð????????????UH??SH??=0 uK?`H?* H???`H??H??H9?s$fDH??H? ???`H?? H9?r??? H?[]?fff.?H?= UH??t?H??]`??]Ð?UH??SH???dH?%(H?E?1?Dž????Dž????Dž????H??????H???T???????H???????#H???????|H??0?????????Hc?H??H?H??????H??H???$?????????H????0????ƿ? `?Y?????
#H???
?????????H????0?????1 ???????????????????H??????H???????????d???H??????H???R???????????????????????ƿ? `??????%#H????????H???????6#H?????????
#H???`????H??????H?????????H?U?dH3%(t$?H??H??????H???????H??H???L????????H???[]?UH??H???}??u??}?u*?}???u!??!`?6????P
#?? `??!`H?????????UH?????????]?UH??}??u??U??E? ?]Ð???H?l$?L?d$?H?-? L?%? L?l$?L?t$?L?|$?H?\$?H??8L)?A??I??H??I???k???H??t1?#L??L??D??A??H??H9?u?H?\H?l$L?d$L?l$ L?t$(L?|$0H??8???Ð?????????????UH??SH?H H???t??`DH???H?H???u?H?[]Ð?H??_???H??exam.txtstudents out of did not pass the exam.D????`?????s?????????????????0p???XzRx
$H??? FJ
O ??;*3$"D8???A?C
I used this command: g++ main.cpp -o output.out
Is there something wrong with my command?
Thank you so much!!!
You're doing some dodgey things. As mentioned already, don't test eof. You actually need to test whether your input was successful and/or whether the stream is good. You can have a catch-all when you're reading streams:
while( infile )
{
//...
}
I mentioned also that you need to check that the value was read. It could be that an integer cannot be read because the input stream does not contain something that looks like an integer, or perhaps some other error occurred. Since you're only reading one integer at a time, you can test that operation by itself. If the stream was bad to begin with (eg the file could not be opened) it will fail straight away:
while( infile >> input[x] )
{
//...
}
I wouldn't generally use the above approach if reading more than one value each time, because the loop condition gets cluttered. Here's an alternative:
while( infile )
{
if( !(infile >> input[x]) ) {
cout << "Failed to read value " << x+1 << endl;
break;
}
//...
}
Let's roll with that, because it's more useful when you wanna find out what's going on. The next thing is that you have a fixed-size array with 100 values. If you read too many values, you are going to overflow. So you need to make sure this won't happen:
while( infile && x < 100 )
{
if( !(infile >> input[x]) ) {
cout << "Failed to read value " << x+1 << endl;
break;
}
cout << input[x] << endl;
if( input[x] < 50 ) {
fail++;
} else {
pass++;
}
x++;
}
Now, it seems to me that you're not even using the array, so why keep it at all? You could just read into a temporary value:
int grade;
if( !(infile >> grade) ) break;
// ...
But if you wanted to keep the array and didn't know how many grades you might end up reading, use a vector<int> instead of an int array. I'll show this with the simpler loop style:
std::vector<int> grades;
int grade;
while( infile >> grade )
{
grades.push_back(grade);
//...
}
Notice how I've used more descriptive variable names. Something like input doesn't tell you much about what it contains. That is the kind of variable name you'd get from an inexperienced programmer whose YouTube videos you should immediately boycott.
The last thing I'll suggest is using ifstream instead of fstream, because by default you don't need to open the file in read/write mode. You could supply flags to fstream::open, but why do that when you can just construct ifstream like this:
ifstream infile("exam.txt");
You also don't need to explicitly close it, because that will happen when infile's destructor is called.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
void main ()
{
string STRING;
ifstream infile;
infile.open ("names.txt");
while(!infile.eof) // To get you all the lines.
{
getline(infile,STRING); // Saves the line in STRING.
cout<<STRING; // Prints our STRING.
}
infile.close();
system ("pause");
}
I hope, this code can help you.

Assign last number of a text file to a variable C++

I am doing a program that outputs a list of prime numbers with fstream.
I have this so far:
int export_list (int lim = 50)
{
int x;
last_in_txt = ????????????; // assigns last number on txt
ofstream file ("Primes.txt" , ios::app);
if (file.is_open()) // if it opens correctly
{
for (x = last_in_txt ; x < lim ; x++)
{
if (check_prime (x)) // returns 1 when x is prime, returns 0 when not
{
file<< x << " ";
}
}
cout << "Done!" << endl << pressenter;
cin.get();
}
else
{
cout << "Unable to open file" << endl << pressenter;
cin.get();
}
return(0);
}
So, as you can see, this should append a list of prime numbers to Primes.txt, starting with the prime 1234547.
Primes.txt looks like this:
2 3 5 7 11 13 17 19 23 29 31 37 (...) 1234543 1234547
My question is how do I assign 1234547 (which is the last number of the txt) to the variable last_in_txt?
Other (not so important) question:
Should I save the numbers the way I'm currently doing, or should I store each number in a separate line?
One simple way: keep reading and assign until the whole file is read.
For example,
int last_in_txt = 0;
{
ifstream infile("Prime.txt");
int k;
while(infile >> k) {
last_in_txt = k;
}
}
// Now last_in_txt is assigned properly, and Prime.txt is closed
This works well no matter the numbers in Prime.txt are separated by space characters (' ') or by newline characters ('\n').
My suggestion is that you write using binary format into the text file(using wb in C). In this case you will know how many bytes does the last number occupy and you will be able to use seekg and tellg to get it. If you use plain text format you will have to read char by char from the end and this is more error-prone and also slower.