Can anyone tell me why the below piece of code I wrote when compiling keeps complaining istream_iterator is not a member of std please can you tell?
Thanks guys
#include <cstdlib>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string.h>
#include <vector>
#include <fstream>
//#include<sstream>
struct field_reader: std::ctype<char> {
field_reader(): std::ctype<char>(get_table()) {}
static std::ctype_base::mask const* get_table() {
static std::vector<std::ctype_base::mask>
rc(table_size, std::ctype_base::mask());
rc[';'] = std::ctype_base::space;
return &rc[0];
}
};
struct Stud{
double VehicleID;
double FinancialYear;
double VehicleType;
double Manufacturer;
double ConditionScore;
friend std::istream &operator>>(std::istream &is, Stud &s) {
return is >> s.VehicleID >> s.FinancialYear >> s.VehicleType >> s.Manufacturer >> s.ConditionScore;
}
// we'll also add an operator<< to support printing these out:
friend std::ostream &operator<<(std::ostream &os, Stud const &s) {
return os << s.VehicleID << "\t"
<< s.FinancialYear << "\t"
<< s.VehicleType << "\t"
<< s.Manufacturer << "\t"
<< s.ConditionScore;
}
};
int main(){
// Open the file:
std::ifstream in("VehicleData_cs2v_1.csv");
// Use the ctype facet we defined above to classify `;` as white-space:
in.imbue(std::locale(std::locale(), new field_reader));
// read all the data into the vector:
std::vector<Stud> studs{(std::istream_iterator<Stud>(in)),
std::istream_iterator<Stud>()};
// show what we read:
for (auto s : studs)
std::cout << s << "\n";
}
So please if you spot the issue let me know as I can't quite tell at the moment and I believe I put in all the necessary include libraries
The error message may sound a bit misleading, but it's the best thing the compiler could say. std::istream_iterator is declared in the <iterator> header file, that's what causes your problem.
Just add this to your includes
#include <iterator>
Related
I'm using Redis with C++, so I'm using redis-cpp library to use it with this language. I'm trying to understand RESP protocol. As far as I know, this protocol can serialize and deserialize simple strings, errors, integers, bulk strings and arrays. I want to serialize and deserialize hash too, so I was trying to implement the code but is not as easy as I tough. This library implments some examples, so I was just trying to modify one of these examples:
Here is where data is called:
#include <cstdlib>
#include <iostream>
#include <sstream>
#include <redis-cpp/execute.h>
namespace resps = rediscpp::resp::serialization;
namespace respds = rediscpp::resp::deserialization;
auto make_sample_data()
{
std::ostringstream stream;
put(stream, resps::array{
resps::simple_string{"This is a simple string."},
resps::error_message{"This is an error message."},
resps::bulk_string{"This is a bulk string."},
resps::integer{100500},
resps::array{
resps::simple_string("This is a simple string in a nested array."),
resps::bulk_string("This is a bulk string in a nested array.")
}
});
return stream.str();
}
I want to add a line similar to the others like: resps::hash(-add here an string, an integer, etc-)
And main function looks like this:
{
try
{
auto const data = make_sample_data();
std::cout << "------------ Serialization ------------" << std::endl;
std::cout << data << std::endl;
std::cout << "------------ Deserialization ------------" << std::endl;
std::istringstream stream{data};
print_sample_data(stream, std::cout);
std::cout << std::endl;
}
catch (std::exception const &e)
{
std::cerr << "Error: " << e.what() << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
Serialization function of simple_string, for example, is build like this:
#ifndef REDISCPP_RESP_SERIALIZATION_H_
#define REDISCPP_RESP_SERIALIZATION_H_
// STD
#include <cstdint>
#include <forward_list>
#include <ostream>
#include <string_view>
#include <type_traits>
#include <tuple>
#include <utility>
// REDIS-CPP
#include <redis-cpp/detail/config.h>
#include <redis-cpp/resp/detail/marker.h>
#include <redis-cpp/resp/detail/overloaded.h>
namespace rediscpp
{
inline namespace resp
{
namespace serialization
{
template <typename T>
void put(std::ostream &stream, T &&value)
{
value.put(stream);
}
class simple_string final
{
public:
simple_string(std::string_view value) noexcept
: value_{std::move(value)}
{
}
void put(std::ostream &stream)
{
stream << detail::marker::simple_string
<< value_
<< detail::marker::cr
<< detail::marker::lf;
}
private:
std::string_view value_;
};
And deserialization for same function is build like this:
#ifndef REDISCPP_RESP_DESERIALIZATION_H_
#define REDISCPP_RESP_DESERIALIZATION_H_
// STD
#include <cstdint>
#include <istream>
#include <stdexcept>
#include <string>
#include <string_view>
#include <variant>
#include <vector>
// REDIS-CPP
#include <redis-cpp/detail/config.h>
#include <redis-cpp/resp/detail/marker.h>
namespace rediscpp
{
inline namespace resp
{
namespace deserialization
{
[[nodiscard]]
auto get_mark(std::istream &stream)
{
switch (stream.get())
{
case detail::marker::simple_string :
return detail::marker::simple_string;
case detail::marker::error_message :
return detail::marker::error_message;
case detail::marker::integer :
return detail::marker::integer;
case detail::marker::bulk_string :
return detail::marker::bulk_string;
case detail::marker::array :
return detail::marker::array;
default:
break;
}
throw std::invalid_argument{
"[rediscpp::resp::deserialization::get_mark] "
"Bad input format."
};
}
template <typename T>
[[nodiscard]]
T get(std::istream &stream)
{
return {stream};
}
class simple_string final
{
public:
simple_string(std::istream &stream)
{
std::getline(stream, value_);
value_.pop_back(); // removing '\r' from string
}
[[nodiscard]]
std::string_view get() const noexcept
{
return value_;
}
private:
std::string value_;
};
How can I add hash as a type and build the functions in serialize and deserialize as it was done with simple_string? Thanks in advance!!
I'm having trouble with a basic stream insertion overload. The code is fairly self-explanatory:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <map>
#include <string>
class dictionary
{
public:
using map_type = std::map<std::string, std::string>;
using ostream_iterator_type = std::ostream_iterator<map_type::value_type>;
private:
map_type inner;
public:
dictionary() : inner()
{
inner["foo"] = "lorem";
inner["baz"] = "ipsum";
}
void
write(std::ostream& os)
{
os << "{\n";
std::copy(std::begin(inner), std::end(inner), ostream_iterator_type(os, "\n"));
os << "}";
}
};
dictionary::ostream_iterator_type::ostream_type&
operator<<(dictionary::ostream_iterator_type::ostream_type& os,
dictionary::map_type::value_type const& p)
{
os << p.first << " => " << p.second;
return os;
}
This code throws some huge template errors, claiming that there's no appropriate overload for operator<< with the two arguments that I've clearly defined. What obvious problem am I missing?
Thanks!
The first thing I've noticed is the lack of <ostream> and <algorithm> includes. Also you seem to define operator << only after it is required. But the real problem is that you are trying to define operator << taking ::std::pair as second parameter outside of std namespace. You can fix it appropriately redefining it like this:
#include <iterator>
#include <map>
#include <string>
#include <ostream>
#include <algorithm>
class dictionary
{
public:
using map_type = std::map<std::string, std::string>;
private:
map_type inner;
public:
dictionary() : inner()
{
inner["foo"] = "lorem";
inner["baz"] = "ipsum";
}
void
write(std::ostream& os);
};
namespace std
{
std::ostream &
operator <<(std::ostream & os, dictionary::map_type::const_reference & p)
{
os << p.first << " => " << p.second;
return os;
}
} // namespace std
void dictionary::
write(std::ostream& os)
{
using ostream_iterator_type = std::ostream_iterator<map_type::value_type>;
os << "{\n";
std::copy(std::begin(inner), std::end(inner), ostream_iterator_type(os, "\n"));
os << "}";
}
I'm trying to define the << operator for a base class, so I can later print the identifier of each object easily.
I have tried an SSCCE, but I don't really know where the problem is, since I'm printing a direction and not the content. I don't know if the problem appears by printing the vector position, or by printing the std::string(char[]).
main.cpp:
#include "City.h"
#include <vector>
#include <iostream>
int main() {
std::vector<Location*> locations;
locations.push_back(new City("TEST"));
for(unsigned int it = 0; it<locations.size(); it++){
std::cout << locations[it] << std::endl;
}
return 0;
}
Location.h:
#include <cstring>
#include <string>
class Location {
public:
Location(const std::string id);
friend std::ostream& operator<<(std::ostream& os, Location& loc);
std::string GetId();
private:
// Name/identifier of the location
char ID[5];
};
Location.cpp:
#include "Location.h"
Location::Location(const std::string id){
memset(this->ID, 0, 5);
strncpy(this->ID, id.c_str(), 5); // I have it as a char[5] at a larger app
}
std::string Location::GetId(){
return std::string(this->ID);
}
std::ostream& operator<<(std::ostream& os, Location& loc){
os << loc.GetId();
return os;
}
City.h:
#include "Location.h"
class City: public Location{
public:
City(std::string id);
};
City.cpp:
#include "City.h"
City::City(const std::string id) : Location(id){
}
Any idea?
I am developing a program in c++ with lots of file io operation. I have defined a static ofstream in a common header so that it is accessible everywhere in the project. The structure of the codes are list as following: all common variable are defined in com.h, test.h and test.cpp are for a class called OPClass, main.cpp carry the main program
COM.H:
#ifndef __CLCOM__
#define __CLCOM__
#include <sstream>
#include <fstream>
#include <iostream>
using namespace std;
static ofstream out;
static stringstream ss;
#endif
TEST.H:
#ifndef __CL__
#define __CL__
#include <iostream>
#include <fstream>
#include "com.h"
using namespace std;
class OPClass
{
public:
void run(void);
void show(ostream &o) const;
};
#endif
TEST.CPP:
#include "com.h"
#include "test.h"
void OPClass::run(void)
{
out << "Here is run()" << endl;
show(out);
}
void OPClass::show(ostream &o) const
{
o << "hello!" << endl;
}
MAIN.CPP:
#include "com.h"
#include "test.h"
void runmain(void)
{
OPClass op;
out.open("output.txt", ios::out | ios::trunc);
out << endl << "State changed!" << endl;
op.run();
if (out.is_open()) out.close();
}
int main(int argc, char* argv[])
{
runmain();
return 0;
}
As you can see, the static ofstream was named as out and will be called in the main program and in the class. I am using mingw32 and didn't see any problem on compilation or upon running. But seems that only the information in runmain() will be written to the output file. Any other message written to that file in the class never appear in the output file. Why's that and how can I written a common file stream so everywhere in the project can access that? Thanks.
Each compilation unit is getting its own ss and out. Hence there is a different instance of them seen by main.cpp than by test.cpp.
You don't really need static here. To address this, rather than declaring the variables and their allocations in the header file you need to merely prototype them using the extern keyword.
#ifndef __CLCOM__
#define __CLCOM__
#include <sstream>
#include <fstream>
#include <iostream>
// Note: don't put "using" statements in headers
// use fully qualified names instead
extern std::ofstream out;
extern std::stringstream ss;
#endif
Where you actually put your declarations is up to you, just make sure it's only in one place. That could be a com.cpp file or you could stick it in main.cpp if that's appropriate for your project.
std::ofstream out;
std::stringstream ss;
Not that global variables like this are a good idea, anyway...
Preemptive statement: You should accept #HostileFork's answer.
Just as an addendum, an easy way to show what's happening is to print out the address of out whenever you try to use it.
If you add these couple statements:
void OPClass::run(void)
{
cout << "Address of 'out' = " << &out << endl;
out << "Here is run()" << endl;
show(out);
}
And:
void runmain(void)
{
cout << "Address of 'out' = " << &out << endl;
OPClass op;
out.open("output.txt", ios::out | ios::trunc);
out << endl << "State changed!" << endl;
op.run();
if (out.is_open()) out.close();
}
You'll notice that the two print statements for out display two different addresses. This should tell you that you're actually getting two instances of out created as two distinct variables. The methods in your OPClass are trying to write to a completely different output stream. It has to do with the way you're using static in a global context; it doesn't behave like you think it does. In a global context, declaring something static binds it to the local scope of the file it's in.
I created a small sample for testing the boost serialization library, but I have a compilation problem.
First of all, here's the code:
#include <iostream>
#include <fstream>
#include <iomanip>
#include <boost/filesystem/operations.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/archive/xml_iarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/serialization/utility.hpp>
#include <boost/serialization/list.hpp>
#include <boost/serialization/version.hpp>
std::vector<uint8_t> buf;
class MyClass
{
public:
MyClass(){};
virtual ~MyClass(){};
int assetStatus;
friend class boost::serialization::access;
template<typename Archive> void serialize(
Archive & ar,
const unsigned int version)
{
ar & BOOST_SERIALIZATION_NVP(assetStatus);
}
std::string ToString()
{
std::string toret;
toret += " assetStatus: " + assetStatus;
return toret;
}
};
int main()
{
MyClass a, b;
a.assetStatus = 10;
std::cout << a.ToString();
boost::archive::xml_oarchive ooxml(std::ofstream(dbPath));
ooxml << BOOST_SERIALIZATION_NVP(a); // error here
MyClass d;
boost::archive::xml_iarchive iixml(std::ifstream(dbPath));
iixml >> BOOST_SERIALIZATION_NVP(d); // error here
std::cout << d.ToString();
}
I get a compilation error at the lines:
ooxml << BOOST_SERIALIZATION_NVP(a);
and
iixml >> BOOST_SERIALIZATION_NVP(d);
The error is:
no match for operator>> in 'iixml >> boost::serialization::make_nvp(const char*, T&) [with T=MyClass(((MyClass&)(&d)))]'
Do you have any idea regarding the meaning of this?
It looks like dbPath is not defined. Additionally, the declaration of ooxml/iixml appears incorrect.
Try modifying your code to do the following:
...
const char * dbPath = "file.xml"
std::ofstream ofs(dbPath);
boost::archive::xml_oarchive ooxml(ofs);
ooxml << BOOST_SERIALIZATION_NVP(a);
std::ifstream ifs(dbPath);
boost::archive::xml_iarchive iixml(ofs);
iixml >> BOOST_SERIALIZATION_NVP(d);
I think NVP (name value pair) is not supported for reading (i.e. with iixml), either use & (instead of >>) or iixml >> d;