I'm fairly new to C++, and am trying to get the istream to work. I have a class of:
class rat
{
private:
int num;
int denom;
public:
rat();
rat(const int&, const int&);
rat(const int&);
friend ostream& operator << (ostream&, const rat&);
friend istream& operator >> (istream&, const rat&);
};
rat::rat(void)
{
num = 0;
denom = 1;
}
rat::rat(const int &n, const int &d)
{
num = n;
denom = d;
simplify();
}
rat::rat(const int &n)
{
num = n;
denom = 1;
}
ostream& operator << (ostream &os, const rat &r1)
{
os << r1.num;
os << "/";
os << r1.denom;
return os;
}
istream& operator >> (istream &is, const rat &r1)
{
is >> r1.num;
is >> r1.denom;
return is;
}
I also have a .cpp of:
#include <iostream>
#include <conio.h>
using namespace std;
#include "Rats.h"
void main()
{
rat r1(3,4), r2(2,3), r3;
system("cls");
cout << "Please enter a rational number: ";
cin >> r3;
}
My problem occurs whenever it comes across the "is >> r1.num;" line. It gives me the error: Unhandled exception at 0x772d15de in RatClass.exe: 0xC00000FD: Stack overflow.
Again, I'm fairly new, so have not learned what the possible cause could be yet. Any help is appreciated.
Looks like it might be the fact that you're accepting const rat &r1 but by sending data from the istream you would be changing r1. You can't change constants. Not sure if this is the issue but that's the first obvious thing that came to mind.
Try this:
istream& operator >> (istream &is, rat &r1)
{
is >> r1.num;
is >> r1.denom;
return is;
}
Don't forget to change your definition in the class:
friend istream& operator >> (istream&, rat&);
Related
#include <string>
#include <iostream>
#include <vector>
#include <map>
using std::map;
using std::vector;
using std::string;
typedef map<char, int> edges;
typedef vector<edges> trie;
trie build_trie(vector<string> & patterns) {
trie t;
// write your code here
for(int j=0;j<patterns.size();j++){
//current NOde = root;
int currNI=0;
for(int i=0;i<patterns[j].size();i++){
char currS = patterns[j][i];
auto it = t[currNI].begin();
//auto mit = it->edges.begin();
if(t[currNI].edges.find(currS)!=t[currNI].edges.end()){
currNI = t[currNI].edges.find(currS)->second;
}else{
t.push_back(edges.insert(currS,t.size()));
t[currNI].edges.insert(currS,t.size());
currNI = t.size();
}
}
}
return t;
}
int main() {
size_t n;
std::cin >> n;
vector<string> patterns;
for (size_t i = 0; i < n; i++) {
string s;
std::cin >> s;
patterns.push_back(s);
}
trie t = build_trie(patterns);
for (size_t i = 0; i < t.size(); ++i) {
for (const auto & j : t[i]) {
std::cout << i << "->" << j.second << ":" << j.first << "\n";
}
}
return 0;
}
Hi I was trying to build trie using vector and map but I am not able to access elements of map.
I have also added image of pseudo code for better clarity.
I have used iterators and many other tricks that are already present on stackoverflow and on other platform but somehow I am not able to access what I want.
Thank You
To answer your questions: in your code, edges is a type, not an object.
t[currNI] is of type edges, thus is a map<char, int>.
You should try t[currNI].find(currS) and t[currNI].end() directly.
NB: after you fix this, there are still other errors in your code.
I am a new man on using spirit x3, I read some document from official site or from other github repositories. But, I can not find how to parse into a class with parameters. I referred to the former question: Boost-Spirit (X3) parsing without default constructors
I wrote a sample to test it, I will present my codes in the following area. My pain is how to use x3::_attr, and how to pass parsed parameters to the class constructor?
#include <boost/spirit/home/x3.hpp>
#include <iostream>
#include <vector>
struct MyPair {
MyPair(int x, int y) : mx(x), my(y) {};
int mx;
int my;
};
class MyDu {
public:
MyDu() {};
MyDu(int x, int y) : mx(x), my(y) {};
int mx;
int my;
};
int main()
{
namespace x3 = boost::spirit::x3;
using x3::int_;
std::vector<MyPair> pairs;
MyDu myDu;
char const *first = "11:22", *last = first + std::strlen(first);
//auto pair = x3::rule<struct pair_, std::vector<MyPair> >{}
// = (int_ >> ':' >> int_)
// [([&](auto& ctx) {
// auto& attr = x3::_attr(ctx);
// using boost::fusion::at_c;
// return x3::_val(ctx).emplace_back(at_c<0>(attr), at_c<1>(attr));
// })]
//;
auto pair = x3::rule<class MyDu_, MyDu >{}
= (int_ >> ':' >> int_)
[([&](auto& ctx) {
auto& attr = x3::_attr(ctx);
using boost::fusion::at_c;
//return x3::_val(ctx)(at_c<0>(attr), at_c<1>(attr));
ctx = MyDu(at_c<0>(attr), at_c<1>(attr));
return x3::_val(ctx);
})]
;
//bool parsed_some = parse(first, last, pair % ',', pairs);
bool parsed_some = parse(first, last, pair, myDu);
if (parsed_some) {
std::cout << "Parsed the following pairs" << std::endl;
//for (auto& p : pairs) {
// std::cout << p.mx << ":" << p.my << std::endl;
//}
std::cout<<myDu.mx<<","<<myDu.my<<std::endl;
}
system("pause");
}
Any one who can fix my error, and parse into a class in my code ? Thanks!
Perhaps you were missing the way to assign to the rule's value using _val:
Live On Coliru
#include <boost/spirit/home/x3.hpp>
#include <iostream>
#include <vector>
struct MyDu {
MyDu(int x, int y) : mx(x), my(y){};
int mx;
int my;
};
int main() {
namespace x3 = boost::spirit::x3;
using x3::int_;
MyDu myDu{1,2};
std::string const s = "11:22";
auto assign = [](auto& ctx) {
using boost::fusion::at_c;
auto& attr = x3::_attr(ctx);
x3::_val(ctx) = MyDu(at_c<0>(attr), at_c<1>(attr));
};
auto pair = x3::rule<class MyDu_, MyDu>{} = (int_ >> ':' >> int_)[assign];
if (parse(begin(s), end(s), pair, myDu)) {
std::cout << "Parsed: " << myDu.mx << ", " << myDu.my << "\n";
}
}
Prints
Parsed: 11, 22
Oh, fantastic! Many thanks, sehe, you help me solve the problem bothering me for some while.
In fact I can not find document on spirit how to use attr, i only find a doc from "Ruben-Van-Boxem-Parsing-CSS-in-C-with-Boost-Spirit-X3",
_val :A reference to the attribute of the innermost rule invoking _where :the parser Iterator range to the input stream
_attr : A reference to the a˛ribute of the parser
_pass: A reference to a bool flag that can be used to force the parser to fail
could you share some info on these parameters. Many thanks again!
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 years ago.
Improve this question
I wrote a small test to figure out the fastest mathematic operation for a special x. I wanted the x to be entered by the user, so that I can run the tests for different x. In the following code I tells me that there is an error with std::cin >> val;
error: cannot bind 'std::istream {aka std::basic_istream}' lvalue to 'std::basic_istream&&'
If I declare val as double valinstead of const double val I get more errors. What can I change in order to have a running programm?
#include <cmath>
#include <chrono>
#include <iomanip>
#include <iostream>
#include <istream>
#include <ostream>
// for x^1.5
double test_pow_15(double x) { return std::pow(x, 1.5); };
double test_chain_15(double x) { return sqrt(x * x * x); };
double test_tmp_15(double x) { double tmp = x * x * x; return sqrt(tmp); };
volatile double sink;
const double val = 0;
const double ans_15 = std::pow(val, 1.5);
void do_test(const char* name, double(&fn)(double), const double ans) {
auto start = std::chrono::high_resolution_clock::now();
for (size_t n = 0; n < 1000 * 1000 * 10; ++n) {
sink = val;
sink = fn(sink);
}
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::milli> dur = end - start;
std::cout << name << ".Took" << dur.count() << "ms, error:" << sink - ans << '\n';
}
int main()
{
std::cout << "Speed test"<< '\n';
std::cout << "Please enter value for x."<< '\n';
std::cout << "x = ";
std::cin >> val;
std::cout << "Speed test starts for x = "<< val <<"."<<'\n';
std::cout << " " << '\n';
std::cout << "For " << val<<"^(1.5) the speed is:" <<'\n';
do_test("std::pow(x,1.5) ",test_pow_15, ans_15);
do_test("sqrt(x*x*x) ",test_chain_15, ans_15);
do_test("tmp = x*x*x; sqrt(tmp) ",test_tmp_15, ans_15);
return 0;
}
I think if you remove the "const" keyword, it would probably work fine.
double val = 0;
What is the best way to store the state of a C++11 random generator without using the iostream interface. I would like to do like the first alternative listed here[1]? However, this approach requires that the object contains the PRNG state and only the PRNG state. In partucular, it fails if the implementation uses the pimpl pattern(at least this is likely to crash the application when reloading the state instead of loading it with bad data), or there are more state variables associated with the PRNG object that does not have to do with the generated sequence.
The size of the object is implementation defined:
g++ (tdm64-1) 4.7.1 gives sizeof(std::mt19937)==2504 but
Ideone http://ideone.com/41vY5j gives 2500
I am missing member functions like
size_t state_size();
const size_t* get_state() const;
void set_state(size_t n_elems,const size_t* state_new);
(1) shall return the size of the random generator state array
(2) shall return a pointer to the state array. The pointer is managed by the PRNG.
(3) shall copy the buffer std::min(n_elems,state_size()) from the buffer pointed to by state_new
This kind of interface allows more flexible state manipulation. Or are there any PRNG:s whose state cannot be represented as an array of unsigned integers?
[1]Faster alternative than using streams to save boost random generator state
I've written a simple (-ish) test for the approach I mentioned in the comments of the OP. It's obviously not battle-tested, but the idea is represented - you should be able to take it from here.
Since the amount of bytes read is so much smaller than if one were to serialize the entire engine, the performance of the two approaches might actually be comparable. Testing this hypothesis, as well as further optimization, are left as an exercise for the reader.
#include <iostream>
#include <random>
#include <chrono>
#include <cstdint>
#include <fstream>
using namespace std;
struct rng_wrap
{
// it would also be advisable to somehow
// store what kind of RNG this is,
// so we don't deserialize an mt19937
// as a linear congruential or something,
// but this example only covers mt19937
uint64_t seed;
uint64_t invoke_count;
mt19937 rng;
typedef mt19937::result_type result_type;
rng_wrap(uint64_t _seed) :
seed(_seed),
invoke_count(0),
rng(_seed)
{}
rng_wrap(istream& in) {
in.read(reinterpret_cast<char*>(&seed), sizeof(seed));
in.read(reinterpret_cast<char*>(&invoke_count), sizeof(invoke_count));
rng = mt19937(seed);
rng.discard(invoke_count);
}
void discard(unsigned long long z) {
rng.discard(z);
invoke_count += z;
}
result_type operator()() {
++invoke_count;
return rng();
}
static constexpr result_type min() {
return mt19937::min();
}
static constexpr result_type max() {
return mt19937::max();
}
};
ostream& operator<<(ostream& out, rng_wrap& wrap)
{
out.write(reinterpret_cast<char*>(&(wrap.seed)), sizeof(wrap.seed));
out.write(reinterpret_cast<char*>(&(wrap.invoke_count)), sizeof(wrap.invoke_count));
return out;
}
istream& operator>>(istream& in, rng_wrap& wrap)
{
wrap = rng_wrap(in);
return in;
}
void test(rng_wrap& rngw, int count, bool quiet=false)
{
uniform_int_distribution<int> integers(0, 9);
uniform_real_distribution<double> doubles(0, 1);
normal_distribution<double> stdnorm(0, 1);
if (quiet) {
for (int i = 0; i < count; ++i)
integers(rngw);
for (int i = 0; i < count; ++i)
doubles(rngw);
for (int i = 0; i < count; ++i)
stdnorm(rngw);
} else {
cout << "Integers:\n";
for (int i = 0; i < count; ++i)
cout << integers(rngw) << " ";
cout << "\n\nDoubles:\n";
for (int i = 0; i < count; ++i)
cout << doubles(rngw) << " ";
cout << "\n\nNormal variates:\n";
for (int i = 0; i < count; ++i)
cout << stdnorm(rngw) << " ";
cout << "\n\n\n";
}
}
int main(int argc, char** argv)
{
rng_wrap rngw(123456790ull);
test(rngw, 10, true); // this is just so we don't start with a "fresh" rng
uint64_t seed1 = rngw.seed;
uint64_t invoke_count1 = rngw.invoke_count;
ofstream outfile("rng", ios::binary);
outfile << rngw;
outfile.close();
cout << "Test 1:\n";
test(rngw, 10); // test 1
ifstream infile("rng", ios::binary);
infile >> rngw;
infile.close();
cout << "Test 2:\n";
test(rngw, 10); // test 2 - should be identical to 1
return 0;
}
I need to read a text file which is for example like bottom :
8.563E+002 2.051E+004 4.180E-004 7.596E-001 5.260E-005 6.898E-002 1.710E-001 8.053E-011 2.686E-013 8.650E-012
each of this 10 scientific digits are the specific value of one line it means each line contains 10 value like above, There is one such line for every grid point in each file. The X indices value most rapidly, then Y, then Z; the first line in the file refers to element (0,0,0); it means the first 10 values presents the first line which refers to element (0,0,0) and the second line (second 10 values) to second element (1,0,0); the last to element (599,247,247).
I don't know how can I write the code for this file using visual C++ ,what I know is I have to read this file line by line which can be determined by eliminating 10 values and tokenize it , then I have to create the x y z for each line il end of the line. I know the concept but I don't know How can I code it in visual C++ .. I need to submit it as my homework .. I really welcome every help .. Thanks
core part can look like:
std::ifstream is("test.txt");
std::vector<double> numbers;
for(;;) {
double number;
is >> number;
if (!is)
break;
numbers.push_back(number);
}
I do not have here MSVC but GCC 4.3. I hope this code helps:
#include <iostream>
#include <fstream>
#include <list>
#include <string>
#include <iterator>
using namespace std;
class customdata
{
friend istream& operator>>(istream& in, customdata& o);
friend ostream& operator<<(ostream& out, const customdata& i);
public:
customdata()
: x(0), y(0), z(0)
{}
customdata(const customdata& o)
: x(o.x), y(o.y), z(o.z)
{}
customdata& operator=(const customdata& o)
{
if (this != &o)
{
x = o.x;
y = o.y;
z = o.z;
}
return *this;
}
private:
long double x, y, z;
};
istream& operator>>(istream& in, customdata& o)
{
in >> o.x >> o.y >> o.z;
return in;
}
ostream& operator<<(ostream& out, const customdata& i)
{
out << "x=" << i.x << " y=" << i.y << " z=" << i.z;
return out;
}
// Usage: yourexec <infile>
int main(int argc, char** argv)
{
int exitcode=0;
if(argc > 1)
{
ifstream from(argv[1]);
if (!from)
{
cerr << "cannot open input file " << argv[1] << endl;
exitcode=1;
}
else
{
list<customdata> mydata;
copy(istream_iterator<customdata>(from), istream_iterator<customdata>(), back_inserter(mydata));
if(mydata.empty())
{
cerr << "corrupt input data" << endl;
exitcode=3;
}
else
copy(mydata.begin(), mydata.end(), ostream_iterator<customdata>(cout, "\n"));
}
}
else
{
cerr << "insufficient calling parameters" << endl;
exitcode=2;
}
return exitcode;
}