I have an assignment where I must read from a file and perform various calculations on it and write the answer to an output file. Everything was going great until I came to this step:
"Reread the file and compute the sum of the integers in the file as long as the sum does not exceed 1000. Use a flag controlled loop structure."
My code snippet is as follows:
dataFile2.close();
dataFile2.clear();
dataFile2.open("J:\\datafile2.txt");
sum = 0;
while(sum < 1000)
{
dataFile2 >> num;
sum = sum + num;
if(sum > 1000)
sum = sum - num;
}
answers << "The sum of the integers not exceeding 1000 is " << sum << endl;
cout << "The sum of the integers not exceeding 1000 is " << sum << endl;
return 0;
My variables have already been declared. when I take out the if statement the sum adds the last number and the sum then exceeds 1000. When the If statement is left in, the answers and cout statements are not executed and there are no compiler warnings or errors.
Any help on this would be greatly appreciated.
-ThePoloHobo
Since no one seems to want to give you a correct answer... (and
to be fair, it's hard to give a correct answer without actually
doing your work for you).
There are two issues in you code. The first is the requirement
that you use a flag. As I said in my comment, the idiomatic
solution would not use a flag, but there's no problem using one.
A flag is a boolean variable which will be tested in the
while, and will be set in a conditional in the loop, when you
find something that makes you want to leave the loop.
The second issue is that you are using num without checking
that the input has succeeded. You must check after the >>
operator. The idiomatic way of checking (and the only thing
that should ever be used by someone not experienced in the
language) is to treat the stream as if it were a boolean:
dataFile2 >> num;
if ( dataFile2 ) {
// Input succeeded...
} else {
// Input failed for some reason, maybe end of file
}
Since all operations on a stream return a reference to the
stream, it is usual to merge the test and the input:
if ( dataFile2 >> num ) {
// succeeded
} else {
// failed
}
(Personally, I find the idea of modifying state in the condition
of an if or a while horrible. But this idiom is so
ubiquitous that you should probably use it, for the simple
reason that that's what everyone expects.)
In pedagogical environments, it's probably acceptable to
consider any failure to be end of file, and just move the test
up into the while (except, of course, that you've been asked
to use a flag). In other contexts, you'll want to take into
account the fact that the failure could be due to a syntax error
in the input—someone inserted "abc" into the file where
you were expecting a number. There are a number of ways of
handling this, all of which are beyond the scope of what you are
trying to do, but be aware that after you've detected failure,
you can interogate the stream to know why. In particular, if
dataFile2.eof() is true, then the failure was (probably) due
to you having read all of the data, and everything is fine. (In
other words, failure to read a data is not necessarily an error.
It can be simply end of file.)
You don't seem to be using a flag variable, which could help in this case. Something like this should fix it:
sum = 0;
bool sumUnder1000 = true; //Or the C++ equivalent, I'm a bit rusty
while(sumUnder1000)
{
if(!dataFile2.good()){
sumUnder1000 = false; //We've reached end of file or an error has occurred
return;
}
dataFile2 >> num;
sum = sum + num;
else if(sum > 1000){
sum = sum - num;
sumUnder1000 = false;
}
}
Related
I have started to use C++ programming language as a complete beginner. With the aim of becoming a better programmer for my STEM degree and with the goal of competitive programming in mind. I have started Functions and Loops in C++ recently and there was a problem I was not sure how to approach.
The probelem: "Write a function to check whether a number is prime"
My Approach:
-> I wanted to implement it on my own so I didn't want to copy paste code online where others have used functions with return type bool.
-> Here is the final version of my code that works:
void prime(int k){
for(int k1=2;k1<k;k++){
if(k%k1==0){
cout<<"int is not prime"<<endl;
break;
}
else{
cout<<"int is prime"<<endl;
break;
}
}
}
->I would then call this in int Main() and get the user to input integers and so on.
-> The above code was due to many trial-and-errors on my part and my thought process was as follows: 1)if i don't include the "break;" statement my code results in an infinite loop 2)I needed a way to stop my code from going toward an infinite loop 3) I remember a topic covered in the functions segment of this website , where we can use it to terminate a loop at will. Thats why i incorporated it into my code to produce the final version
My Question:
Can someone explain how the break; statement is working in the context of my code? I know it produces my desired effect but I still haven't gotten an intuition as to how this would do my work.
Many online resources just cite the break statement as something that does so and so and then gives examples. Without going through the code mechanics. Like how a loop would be going through its conditions and then when it encounters the break; statement what does it do? and as a consequence of that what does it do to help my code?
Any advice would be helpful. I still couldn't wrap my head around this the first time I encountered it.
In your case if k % k1 does not show that the k1 being a factor of the k, the loop is broken after the print statement. If the k % k1 does show that the k1 being a factor of the k, it also breaks out of the loop.
So, either of the break statements leads to the loop termination on the first iteration here. If you test for whether a number is being a prime, it does not work.
In essence, you don't need either of the break statements here. They are mostly forced here. Take a look at the following approach:
#include <iostream>
#include <cmath>
bool prime(unsigned k){
if (k != 2) { // Direct check, so to remain similar to the OP's structure of the code
unsigned up_to = sqrt(k) + 1; // Calculate the limit up to which to check
for (unsigned i = 2; i < up_to; ++i) {
if (k % i == 0) {
std::cout << "Is not prime" << std::endl;
return false;
}
else std::cout << "Checking..." << std::endl;
}
}
std::cout << "Is prime" << std::endl;
return true;
}
// Note, we can check just up to the square root of a k
A note on the behavior of the break
The fact that it breaks out the the closest loop to it - has crucial nature for nested loops (all of them: for, while, and do while):
while (/* condition 1 */) // Outer loop
while (/* condition 2 */) // Inner loop
if (/* condition 3 */) break;
Here if the condition 3 is satisfied, the break will lead to break out of the Inner loop but the Outer loop will still continue to iterate.
For more, you may be interested in "How to exit nested loops?" thread. It addresses your second question.
Analogy... I found it in the last place I looked... like always!
Looking for your keys is the LOOP you are in... when you find them... you BREAK out and move on to another task... like maybe getting into your car...
SO if you are IN your car and know your car is where you left your keys... then you are in the PROCESS of getting prepared to drive away... BUT that process requires keys... THUS you change modes/focus and begin a cyclic process of looking for keys... when found to BREAK that searching process IMMEDIATLY and resume what your were doing.
MANY people would make use of the RETURN instrucion in your code pattern... in place of the break! Both do the same thing... however the RETURN is more descriptive english... and one should be concerned with the programmer behind him... Also a bit of digging might show how one is more efficient than the other...
I have a test in a couple of days and I was reviewing the study guide and I came across a question that I wasn't familiar with. It says "Write a while loop that continuously loops until the user inputs a number saved in a variable named myNum between -1 and -100. Use only < and > operators." Can someone give me a clear explanation of what exactly I am supposed to do for this question?
I'm honestly not entirely sure what this question is asking, because it seems a bit ambiguous in the wording, but this is what I would assume they are asking for. I'm not sure how you could get this done with "only" > and < operators, as you need input and possibly output operators (>> and << respectively). Anyway, I hope that this helps, and if its not perfectly correct with what your assignment is, maybe you can see the logic and make the small changes to have it fit better.
I commented each line, even the obvious (which is sort of a no-no when you get into heavier coding), this way all the syntax makes sense.
#include <iostream>
using namespace std;
int main()
{
// Initialize myNum to 1 so that it passes into while-loop
int myNum = 1;
// Continue looping as long if number is less than -100 or greater than -1 (terminating the loop when numbers from -100 to -1 are entered)
while((myNum > -1) || (myNum < -100))
{
// Display "Enter Text" to console
cout << "Enter number: ";
// Allow user to input number
cin >> myNum;
}
}
OK, so the goal of this was to write some code for the Fibonacci numbers itself then take those numbers figure out which ones were even then add those specific numbers together. Everything works except I tried and tried to figure out a way to add the numbers up, but I always get errors and am stumped as of how to add them together. I looked elsewhere but they were all asking for all the elements in the vector. Not specific ones drawn out of an if statement.
P.S. I know system("pause") is bad but i tried a few other options but sometimes they work and sometimes they don't and I am not sure why. Such as cin.get().
P.S.S I am also new to programming my own stuff so I have limited resources as far as what I know already and will appreciate any ways of how I might "improve" my program to make it work more fluently. I also take criticism well so please do.
#include "../../std_lib_facilities.h"
int main(){
vector<int>Fibonacci;
int one = 0;
int two = 1;
int three = 0;
int i = 0;
while (i < 4000000){
i += three;
three = two + one; one = two; two = three;
cout << three << ", ";
Fibonacci.push_back(three);
//all of the above is to produce the Fibonacci number sequence which starts with 1, 2 and adds the previous one to the next so on and so forth.
//bellow is my attempt and taking those numbers and testing for evenness or oddness and then adding the even ones together for one single number.
}
cout << endl;
//go through all points in the vector Fibonacci and execute code for each point
for (i = 0; i <= 31; ++i)
if (Fibonacci.at(i) % 2 == 0)//is Fibonacci.at(i) even?
cout << Fibonacci.at(i) << endl;//how to get these numbers to add up to one single sum
system("pause");
}
Just do it by hand. That is loop over the whole array and and keep track of the cumulative sum.
int accumulator = 0; // Careful, this might Overflow if `int` is not big enough.
for (i = 0; i <= 31; i ++) {
int fib = Fibonacci.at(i);
if(fib % 2)
continue;
cout << fib << endl;//how to get these numbers to add up to one single sum
accumulator += fib;
}
// now do what you want with "accumulator".
Be careful about this big methematical series, they can explode really fast. In your case I think the calulation will just about work with 32-bit integers. Best to use 64-bit or even better, a propery BigNum class.
In addition to the answer by Adrian Ratnapala, I want to encourage you to use algorithms where possible. This expresses your intent clearly and avoids subtle bugs introduced by mis-using iterators, indexing variables and what have you.
const auto addIfEven = [](int a, int b){ return (b % 2) ? a : a + b; };
const auto result = accumulate(begin(Fibonacci), end(Fibonacci), 0, addIfEven);
Note that I used a lambda which is a C++11 feature. Not all compilers support this yet, but most modern ones do. You can always define a function instead of a lambda and you don't have to create a temporary function pointer like addIfEven, you can also pass the lambda directly to the algorithm.
If you have trouble understanding any of this, don't worry, I just want to point you into the "right" direction. The other answers are fine as well, it's just the kind of code which gets hard to maintain once you work in a team or have a large codebase.
Not sure what you're after...
but
int sum=0; // or long or double...
for (i = 0; i <= 31; ++i)
if (Fibonacci.at(i) % 2 == 0) {//is Fibonacci.at(i) even?
cout << Fibonacci.at(i) << endl;//how to get these numbers to add up to one single sum
sum+=Fibonacci.at(i);
}
// whatever
}
Basic idea: Given an array, find all the permutations of that array. Then, take each of those arrays and put it all together. Eg the array {6,5,3,4,1,2} gives you 653412. The permutations work, but I cannot get the integers.
int main ()
{
int myints[] = {2,3,4,5,6,7,8,9};
int k;
int dmartin=0;
int powof10=1;
std::cout << "The 8! possible permutations with 8 elements:\n";
do {
for(k=0; k<8; k++){
std::cout << myints[k] << ' ';
dmartin=myints[8-k-1]*powof10+dmartin;
powof10=powof10*10;
}
cout << "\n" << dmartin << "\n";
} while ( std::next_permutation(myints,myints+8) );
dmartin=0;
return 0;
}
I also have some code that works when you just have one array, but in this case there are thousands. I though I needed to reset dmartin=0 at the end of each while loop so that it didn't keep adding to the previous answer, however when I tried that I got "0" for each of my answers. Without trying to reset, I get answers that seem random (and are negative).
The problem is that you're not resetting your two variables inside your loop, so they'll continue from the values they had during the previous iteration, which will just be wrong, and will quickly overflow, giving seemingly rubbish output. Try putting this at the beginning or the end of the do-while loop:
dmartin = 0;
powof10 = 1;
But you're really overcomplicating it a lot. It would be way simpler to just build the number from the most significant digit instead of the least significant one instead. This would eliminate the need for a powof10 variable. This new for-loop would look like this:
for(k = 0; k < 8; k++){
std::cout << myints[k] << ' ';
dmartin = 10*dmartin + myints[k];
}
That won't work for long, since your integer will soon overflow.
That's probably what you are experiencing when you get negative numbers.
Using an integer to store the result does not seem the most appropriate choice to me. Why not use a string, for instance? That would save you the hassle of reinventing base10 conversion in 2014, and you could easily derive a number from the string when needed.
That won't solve the overflow problem, though.
First point: the code to take a vector of digits and turn them into a single number should almost certainly be written as a function, not just code inside the loop.
Second point: you can use std::string like a container of char, and apply normal algorithms to it.
Seem to me, the lazy way would look like this:
std::string input="23456789";
do {
std::cout<<std::stoi(input)<<"\n";
} while (std::next_permutation(input.begin(), input.end()));
The goal here was to create a program that found and output all the prime numbers between 1 and 100. I've noticed I have a tendency to complicate things and create inefficient code, and I'm pretty sure I did that here as well. The initial code is mine, and everything that I've put between the comment tags is the code given in the book as a solution.
// Find all prime numbers between 1 and 100
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
int counter; // loop counter
int count_two; // counter for second loop
int val; // equals the number of count, used in division to check for primes
bool check;
check = true;
for(counter = 1; counter <= 100; counter++){
val = counter;
for(count_two = 2; count_two <= 9; count_two++){
if((val % count_two) == !(check)){
cout << val << " is a prime number.\n";
}
}
}
return 0;
}
// program didn't work properly because of needless complication; all that needs to be checked for is whether a number is divisible by two
/*
*********correct code***********
#include <iostream>
using namespace std;
int main()
{
int i, j;
bool isprime;
for(i=1; i < 100; i++) {
isprime = true;
// see if the number is evenly divisible
for(j=2; j <= i/2; j++)
// if it is, then it is not prime
if((i%j) == 0) isprime = false;
if(isprime) cout << i << " is prime.\n";
}
return 0;
}
********************************
*/
From what I can gather, I was on a reasonably correct path here. I think I complicated things with the double loop and overuse of variables, which probably led to the program working incorrectly -- I can post the output if need be, but it's certainly wrong.
My question is basically this: where exactly did I go wrong? I don't need somebody to redo this because I'd like to correct the code myself, but I've looked at this for a while and can't quite figure out why mine isn't working. Also, since I'm brand new to this, any input on syntax/readability would be helpful as well. Thanks in advance.
As it is, your code says a number is prime if it is divisible by any of the numbers from 2 to 9. You'll want a bool variable somewhere to require that it's all and not any, and you'll also need to change this line:
if((val % count_two) == !(check)){
Since check = true, this resolves as follows:
if ((val % count_two) == !true){
and
if ((val % count_two) == false){
and
if ((val % count_two) == 0){
(Notice how the value false is converted to 0. Some languages would give a compile error here. C++ converts it into an integer).
This in fact does the opposite of what you want. Instead, write this, which is correct and clearer:
if (val % count_two != 0) {
Finally, one thing you can do for readability (and convenience!) is to write i, j, and k instead of counter, count_two, and count_three. Those three letters are universally recognized by programmers as loop counters.
In addition to the points made above:
You seemed to think you didn't need to have 2 loops. You do need them both.
Currently, in your code, the upper range of the inner loop is in-dependent on the value of your outer loop. But this is not correct; you need to test divisibility up the the sqrt(outer_loop_value). You'll note in your "correct" code they use half of the outer_loop_value - this could be a performance trade off but strictly speaking you need to test up to sqrt(). But consider that your outer loop was up to 7, your inner loop is testing division all the way up to 9 and 7 is in that range. Which means 7 would be reported as not prime.
In your "correct" code the indenting makes the code harder to interpret. The inner for loop only has a single instruction. That loop loops through all possible divisors. This is unnecessary it could break out at the first point that the mod is zero. But the point is that the if(isprime) cout << i << " is prime.\n"; is happening in the outer loop, not the inner loop. In your (un-commented) code you have put that in the inner loop and this results in multiple responses per outer loop value.
Stylistically there is no need to copy the counter into a new val variable.