Reading from a txt file to a struct in c++ [duplicate] - c++

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.
Why is the nr variable in my code incremented way above 5?
When I test how many times the while loop iterates, it cycles way more times than there are elements in my data file, I cannot understand why.
The data file contains - a 1 2 3 b
Here's my code:
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
struct SOMETHING
{
string string[10];
int int_1[100];
};
void main()
{
int nr = 0;
SOMETHING P;
ifstream D("data.txt");
while(!D.eof())
{
nr++;
if (nr == 1 || nr % 5 == 0)
{
D >> P.string[nr];
cout << P.string[nr] << " ";
}
D >> P.int_1[nr];
cout << P.int_1[nr] << " ";
}
D.close();
}

Examining this:
while(!D.eof())
{
nr++;
if (nr == 1 || nr % 5 == 0)
{
D >> P.string[nr];
cout << P.string[nr] << " ";
}
D >> P.int_1[nr];
cout << P.int_1[nr] << " ";
}
The reason your nr variable exceeds 5 is that you aren't resetting nr when your after each successful read of each line. I don't know if that's what you want, but the way you've implemented it has a problem (see below):
Your structure element clearly has space for 10 elements, but you're only checking and storing the elements at indices 1 and those which are multiples of 5: 0, 1, 5, 10, etc.
Using the eof method is bad practice as #P0W has noted in his comment. Use a while loop instead in tandem with std::getline.

The ifstream's internal pointer is not being updated, so the while loop will run indefinitely because eofbit is never set.

Related

Difficulty with testing for ranges of integer values

I am writing filter program grouping kindergarten, preschool and school for ages I wrote if program but it outputs conditions wrong who is willing to take look at my program?
#include<iostream>
using namespace std;
int main() {
int input;// age
int kindergarden , preschool , school;
cin >> input;
if (2 <= 4)
{
cout << "kindergarden" << "\n\n";
if (5 <= 6)
{
cout << "preschool" << "\n\n";
}
else (7 <= 15);
{
cout << "school" << "\n\n";
}
}
}
Your first if statement is if (2 <= 4). This will always be true. 2 is always less than 4. Inside that if statement, is another if statement, asking if 5 <= 6. This will always be true also. Thus, it will output "kindergarten preschool".
I assume you want to check if input is within the two values in your if statements. To do so, you would write
if(2 <= input && input <= 4)
Also, you should bring the second if statement outside of the first. To do that, you should put your } before the second if statement, not after the last one.
Edit: As YSC pointed out, there's another issue: else (7 <= 15);. There are two issues with this:
1) It should be else if(condition), as plain else statements do not expect a condition.
2) It should not end with ;. It should end with { to hold the code that should be executed if the condition is true.
Your first if is wrapped around two others. Because you 're used flat indentation of source code, it's very hard to spot.
if (2 <= input && input <= 4)
{
cout << "kindergarden" << "\n\n";
} // here was your mistake
else if (5 <= input && input <= 6)
{
cout << "preschool" << "\n\n";
}
else if (7 <= input && input <= 15) // ; another mistake
{
cout << "school" << "\n\n";
}
You can make it into one loop actually, in a dozen various ways
#include<iostream>
#include<string>
using namespace std;
int main() {
int input = 0;// age
const struct Cat
{
int age;
string category;
} classes[] = { {2, "kindergarden"}, {5, "preschool"}, {7, "school"}, {16, ""} };
cin >> input;
// without range loop this looks tricky
for(const Cat *c = std::end(classes)-1; c >= std::begin(classes); c-- )
if ( input >= c->age )
{
std::cout << c-> category;
break;
}
}
The only advantage would be aggregation of conditions in one place. Of course, there can be more parameters for condition, e.g. upper and lower bracket instead of lower only.

C++ do while loop not working

I'm trying to make this code work:
#include <iostream>
using namespace std;
int main()
{
int i;
do
{
cout << ("please enter a number between 1 and 10");
cin >> i;
} while(i > 10 && i < 1)
cout << "the square of the number you have entered is " << i*i;
}
Basically, the idea is that a user enters a number between 1 and 10. While the number is not between 1 and 10, it keeps asking the user to enter a number between the values. Then, when the number is between the values, it is squared and returned to the user.
I can't see why this isn't working
Any help is appreciated
You have:
while (i > 10 && i < 1)
You want:
while (i > 10 || i < 1)
while (i > 10 && i < 1)
Your condition is logically faulty; if reinterpreted, it says:
while i is greater than 10 AND i is less than 1
Judging from your code, the || operator should be used:
} while (i > 10 || i < 1);
As others mentioned, your condition is faulty.
a number can't obviously be under 1 AND above 10 at the same time, so the while loop exits immediately after the do statement.
#include <iostream>
using namespace std;
int main()
{
int i;
do
{
cout << ("please enter a number between 1 and 10");
cin >> i;
} while (i < 1 || i > 10)
cout << "the square of the number you have entered is " << i*i;
}
You should use an Or ||, that condition with && will never be true.
The loop condition is wrong and will never loop, as i cannot be less than 1 && greater than 10 at the same time. You should use the logical OR (||) operator instead. In addition, there must be a semicolon placed after the do-while statement. And you probably want and end of line placed after the prompt. Also, you don't want to start the bad habit of polluting the global namespace, even with the awesomeness of std. So:
#include <iostream>
int main()
{
int i;
do {
std::cout << "please enter a number between 1 and 10\n";
std::cin >> i;
} while (i > 10 || i < 1);
std::cout << "the square of the number you have entered is " << i*i << std::endl;
}

Outfile causes crashes with a memory violation [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I am writing a program to convert numbers from decimal to binary. I already have the algorithm correct for it and the program works fine while using cout. However, as soon as I use outfile in my loop the program crashes with error code (0xC0000005).
Here is my source code:
#include <iostream>
#include <iomanip>
#include <fstream>
#include <cmath>
using namespace std;
int main()
{
int num, remainder_count;
ifstream infile; //define new input file stream
ofstream outfile; //define new output file stream
infile.open("C:\\Users\\Arctic-Gaming\\CLionProjects\\working\\Source\\Binary Conversion (Loop w File)\\Binary Input.txt"); //connect the stream to an actual file
if (!infile)
{
cout << "Cannot open input file! Program aborted" << endl;
return 1;
}
outfile.open("C:\\Users\\Arctic-Gaming\\CLionProjects\\working\\Source\\Binary Conversion (Loop w File)\\Decimal Output.txt"); //connect the stream to an actual file
do
{
int remainder [15] = {0};
remainder_count = 15;
infile >> num;
outfile << "\n" << num << endl;
if (num > 0 && num <= 65535)
{
while (num > 0)
{
remainder[remainder_count] = num % 2;
num /= 2;
remainder_count--;
}
remainder_count = 0;
while (remainder_count < 16)
{
if (remainder_count % 4 == 0)
{
outfile << " ";
}
outfile << remainder[remainder_count];
remainder_count++;
}
}
else if (num == 0)
outfile << "0000 0000 0000 0000" << endl;
else
cout << "Error! Invalid Input." << endl;
}
while (!infile.eof());
}
Your program has undefined behavior by accessing an element out-of-bounds. Since the behavior is undefined, the issue really has nothing to do with using std::cout as opposed to using file streams.
int remainder [15] = {0};
//...
remainder_count = 15;
//...
remainder[remainder_count] = num % 2; // out-of-bounds access (remainder[15] is out-of-bounds)
Once that line above is executed, all bets are off as to how your program will behave. The valid indices of an array range from 0 to n-1, where n is the number of elements in the array. So the valid indices are 0, 1, 2, up to 14 for the remainder array.
If you had switched to using std::array instead of regular C++ arrays, instead of undefined behavior, you would get an std::out_of_range exception thrown as soon as you access that element using at().
std::array<int, 15> remainder= {{0}};
remainder_count = 15;
//...
if (num > 0 && num <= 65535)
{
while (num > 0)
{
remainder.at(remainder_count) = num % 2; //... exception thrown
Live Example
So as you see, your program never "ran fine" as you claimed, and you will have to fix your program so that you are not going out-of-bounds of your array.

Testing Primality in C++ [duplicate]

This question already has answers here:
C - determine if a number is prime
(12 answers)
Closed 9 years ago.
Can anyone help me out? I am trying to test primality but I cant seem to get this to work. For whatever reason, whenever I run it, it runs fine as long as I start with a number that is not prime. However, after running something that is not prime, the output is "0 1" instead of just 0. It also seems that if I start with a number that is not prime, everything is "0 1" instead of the correct output.
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
#include <cmath>
int main()
{
int num;
int x = 2;
//cin >> num;
while(cin >> num) //(x<=num-1)
{
for(x<=num-1; x++;)
{
if(num%x==0)
{
cout << "0" << endl ; //1 is prime, 0 is not prime
break;
}
if(x==num)
{
cout << "1" << endl ;
break;
}
}
if(x==num)
{
cout << "1" << endl ;
}
}
return 0;
}
well you have the cout << "1" twice, you probably didn't mean that
for(x<=num-1; x++;)
the semicolons are in wrong places, so instead of stating a condition x<=num-1 under which execution should happen you state the x<=num-1 expression is just evaluated with no effect and then in case of a prime number x is incremented until
if(num%x==0)
is true because in fact num==x at this point. Then you print your '0' and next you print '1' because
if(x==num)
{
cout << "1" << endl ;
}
is true.

cin.get() not functioning as desired [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Program not waiting for cin
I wrote the following code:
#include <iostream>
using namespace std;
void search(int pre, int a, int b, int x) {
char c;
cout << "Is the number " << ((x == 2) ? b : a) << endl;
c = cin.get(); ////// this does not block
if (c == 'y') return;
else {
cout << "Is the number " << ((x == 2) ? b : a) << " closer to your number than " << pre;
c = cin.get();
if (c == 'y') {
search(a, a, (a + b) / 2, 2);
} //c=='y'
else search(a, (a + b) / 2, b, 1);
}
}
int main() {
int N;
cout << "Enter N? ";
cin >> N;
search(N, 1, N, 1);
return 0;
}
No need to worry if you don't understand the logic because my question is not regarding that.
In the search function, there are two cin.get(), where i need the user to enter a character. My problem is that the the program blocks for input only after the second cin.get().
For example:
Is the number 7 //program doesn't wait after this
Is the number 7 closer to your number than 8 //program blocks here for an input
Why does it do so?
There are at least two problems in your code. The first is that you're
leaving characters in the buffer after inputting N. The simplest
solution is to just add a call to std::cin.ignore( INT_MAX, '\n' );
after std::cin >> N;; a better solution (because it allows for more
error checking) would be to use std::getline to read the complete
line, then parse it using std::istringstream.
The second problem is that you're assigning the results of
std::cin.get() into a char. std::cin.get() returns an int,
which may be EOF. And you really want to check whether it is EOF
before converting the int to char: you cannot check after because
either some legal char will compare equal to EOF (plain char is
signed), or the char will never compare equal to EOF (plain char
is unsigned). The other alternative is to do something like:
if ( !std::cin.get( c ) ) {
// EOF or error seen...
}
each time you want to read a char. (This might be better in your
case, since if you do read EOF, all further calls to std::cin.get()
will return EOF.)