c++ cant resolve variable BOOST_FOREACH - c++

Im trying to use the Boost library, I copied the entire boost folder except for the docs, libs, more, status, tools folders.
When I try to use the code block below, my compiler can't identify 2 things.
vector<string>* read(string & filename)
{
// populate tree structure pt
using boost::property_tree::ptree;
ptree pt;
read_xml(filename, pt);
ptree tree;
vector<string> *ans = new vector<string>();
BOOST_FOREACH( ptree::value_type &v, pt.get_child("computer"))
{
string name = v.first.get<string>("name");
string OS = v.first.get<string>("OS");
ans->push_back(name);
ans->push_back(OS);
}
return ans;
}
'BOOST_FOREACH' was not declared in this scope
Can't resolve struct member 'value_type'
I know the following include lines should be enough:
#include <iostream>
#include <vector>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
If you need more info, please ask.
TIA
EDIT
after adding the include foreach.hpp, im getting:

I know the following include lines should be enough:
Clearly they're not. Add
#include <boost/foreach.hpp>
Fixed code:
Live On Coliru
#include <iostream>
#include <vector>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <boost/foreach.hpp>
std::vector<std::string> read(std::string & filename)
{
// populate tree structure pt
using boost::property_tree::ptree;
ptree pt;
read_xml(filename, pt);
ptree tree;
std::vector<std::string> ans;
BOOST_FOREACH(ptree::value_type &v, pt.get_child("computer"))
{
std::string name = v.second.get<std::string>("name");
std::string OS = v.second.get<std::string>("OS");
ans.push_back(name);
ans.push_back(OS);
}
return ans;
}
int main()
{
}

Related

Visual Studio C++ : read access violation exception in Vector header

I'm replicating the TextQuery example in C++ Primer 5th edition. The code compiles, but it keeps throwing "read access violation" from Vector header when a push_back operation is executed. Here's my code (* is the line with bug):
//main.cpp
#include "stdafx.h"
using namespace std;
int main()
{
ifstream ifile;
ifile.open("D:/OneDrive/Learning/C++/ConsoleApplication1/ConsoleApplication1/testfile.txt");
runQueries(ifile); //*
// ...
}
//stdafx.h
#pragma once
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
#include <vector>
#include <string>
#include <memory>
#include <iostream>
#include <algorithm>
#include <fstream>
#include <iterator>
#include <sstream>
#include <map>
#include <set>
#include "TextQuery.h"
//TextQuery.h
void runQueries(ifstream &infile)
{
TextQuery tq(infile); //*
// ...
}
class TextQuery {
public:
using line_no = std::vector<std::string>::size_type;
TextQuery(std::ifstream&); //*
// ...
private:
std::shared_ptr<std::vector<std::string>> file;
std::map < std::string, std::shared_ptr<std::set<line_no>>> wm;
};
TextQuery::TextQuery(std::ifstream &is)
{
string text;
while (getline(is, text)) {
file->push_back(text); //*
//...
}
}
The next execution will raise an exception in vector header:
bool _Has_unused_capacity() const _NOEXCEPT
{ // micro-optimization for capacity() != size()
return (this->_Myend() != this->_Mylast());
}
Here's the error message:
Exception thrown: read access violation.
std::_Vector_alloc<std::_Vec_base_types<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::allocator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > >::_Myend(...) returned 0xC.
Here's the text file I used for testing:
//text file
text is good
text is good
text is good
text is good
text is good
text is good
text is good
text is good
text is good
As pointed out by #molbdnilo: I forgot to allocate "file".
After changing the constructor to the following, the problem is solve:
TextQuery::TextQuery(std::ifstream &is):file(new vector<string>)
{
string text;
while (getline(is, text)) {
file->push_back(text); //*
//...
}
}

Redefining function in header file c++

After writing my header file and trying to use it in the cpp.file. The compiler gives me an error when trying to redefine the function in header file.
I didn't face this problem the previous times I was using headers in a similar way. Maybe I initialize the Vector in a wrong way. Anyways here is the code:
#include <string>
#include <vector>
#include "lajitellut.h"
using namespace std;
namespace otecpp_lajitellut{
/*this is where the error appears*/
vector<string> lajitellut(int lkm, char*mjt[]){
vector<string> stringVector;
for(int i =0; i<lkm; i++){
stringVector.push_back(mjt[i]);
}
for(int i =0; i<lkm; i++){
for(int a = 0; a<lkm;a++){
if(stringVector[i] < stringVector[a]){
stringVector[i].swap(stringVector[a]);
}
}
}
return stringVector;
}
}
And here is the header file
#ifndef kissa
#define kissa
#include <string>
#include <vector>
namespace otecpp_lajitellut{
std::vector <std::string> lajitellut(int lkm, char* mjt[]) {
std::vector<std::string> stringVector;
return stringVector;
}
}
#endif // kissa
Put only the function declaration in the "lajitellut.h" header file:
#include <vector>
#include <string>
namespace otecpp_lajitellut {
std::vector<std::string> lajitellut(int, char*);
}
Put the function definition in the source "*.cpp" file:
#include <iostream>
#include <vector>
#include <string>
#include "lajitellut.h"
namespace otecpp_lajitellut {
std::vector<std::string> lajitellut(int lkm, char* mjt[]) {
// your code in here
}
}
int main(){
auto a = otecpp_lajitellut::lajitellut(10, "asd");
}
Note that definition is also a declaration. That being said you don't have a vector there. You have a function of type std::vector<std::string>. Don't use using namespace std;.
Ron is right.
Your function lajitellut() is already implemented in the .h file with the same signature. You can not create a double in the same namespace.
You can change the arguments or the type of the return value or change the namespace in the .cpp file.

Trouble returning an object from a class I created

I have this class (hashMap.h):
#pragma once
#include <iostream>
#include <vector>
#include <string>
#include "functions.h"
using std::cout;
using std::vector;
using std::endl;
using std::string;
class hashMap
{
public:
explicit hashMap(int hashEntrySize = 101) : hashVector(nextPrime(2 * hashEntrySize)), currentSize{ 0 }
{}
bool containsKey(const string & searchKey);
bool containsVector(const vector<string> searchVector);
void insert(const string & keyTarget, const vector<string> & insertVector);
void insertAfterReHash(const string & keyTarget, const vector<string> & insertVector);
int getCurrentSize() const;
void assignKey(string & newKey);
private:
enum EntryType { ACTIVE, EMPTY, DELETED };
struct hashEntry
{
vector<string> vectorValue;
EntryType status;
int keyID;
string key;
hashEntry(EntryType s = EMPTY)
:status(s), keyID{ -1 } {}
};
size_t hashFunction(const string & key);
bool isActive(int currentPos) const;
int findPos(const string & keyTarget);
void reHash();
vector<hashEntry> hashVector;
int currentSize;
};
And a function header file (functions.h):
#pragma once
#include <iostream>>
#include <vector>
#include <string>
#include <fstream>
using std::string;
using std::cout;
using std::vector;
using std::endl;
using std::cin;
using std::ifstream;
using std::getline;
hashMap computeAdjacentWords(const vector<string> & words) //error at this line
{
hashMap hm(500);
//do stuff with object
return hm;
}
And the main file:
#include <iostream>>
#include <vector>
#include <string>
#include <fstream>
#include "hashMap.h"
using std::string;
using std::cout;
using std::vector;
using std::endl;
using std::cin;
using std::ifstream;
using std::getline;
int main()
{
vector<string> words;
string line;
ifstream dictionaryFile;
dictionaryFile.open("largedictionary.txt");
words = readinWords(dictionaryFile);
dictionaryFile.close();
hashMap hm = computeAdjacentWords(words);
return 0;
}
I created the hashMap class and I want to be able to return a hashMap object, but this is giving me an error of "Error C4430 missing type specifier - int assumed." What am I doing wrong?
I put the code in files and nicely asked the compiler to do its job. This is the first warning from the list:
$ cc main.cpp -c
In file included from main.cpp:5:
In file included from ./hashMap.h:6:
./functions.h:16:1: error: unknown type name 'hashMap'
hashMap computeAdjacentWords(const vector<string> & words) //error at this line
^
The compiler doesn't know what hashMap is. When it reaches the line with the error, the hashMap symbol was not yet declared or defined.
You shouldn't define functions in header files.
Rename functions.h to functions.cpp, add #include "functions.h" at the end of the list of includes.
Create a new file functions.h that contains only the declarations of the functions (the function header) and the types they use:
#ifndef __FUNCTIONS_H__
#define __FUNCTIONS_H__
#pragma once
//#include <iostream>
#include <vector>
#include <string>
//#include <fstream>
#include "hashMap.h"
using std::string;
using std::vector;
// Do you really need all these types here?
using std::cout;
using std::endl;
using std::cin;
using std::ifstream;
using std::getline;
hashMap computeAdjacentWords(const vector<string> & words);
#endif // __FUNCTIONS_H__
You are including functions.h from hashmap.h BEFORE the hashMap class is defined. As such, when the compiler reads functions.h, the hashMap class is not defined.

.txt to vector <string>, non-class type error

Hi I just started to learn C++ this week and I require some assistance.
Basically what I am trying to do is read from a .txt file and "convert" it into a vector string and then display it.
my error is at this line: text.readFile("scenario.txt"), it says: "request for member 'readFile' in 'text', which is of non-class type 'Conversion()'"
what does that mean?
and also my method getLines() could not be resolved.
main.cpp
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <vector>
#include "Conversion.h"
using namespace std;
int main()
{
vector<string> lines;
Conversion text();
if(text.readFile("scenario.txt") == true)
lines = text.getLines();
for(int i = 0; i < lines.size(); ++i)
cout << lines[i] << endl;
return 0;
}
Conversion.cpp
#include <string>
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include "Conversion.h"
using namespace std;
vector<string> lines;
Conversion::Conversion(std::vector<std::string> lines) {
lines.clear();
}
Conversion::Conversion() {
}
Conversion::~Conversion() {
}
bool Conversion::readFile(string filename) {
ifstream file;
string line;
file.open(filename.c_str());
if(!file.is_open())
return false;
while(getline(file, line))
lines.push_back(line);
return true;
}
vector<string> Conversion::getLines(){
return lines;
}
Conversion.h
#ifndef CONVERSION_H_
#define CONVERSION_H_
#include <string>
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
class Conversion {
public:
Conversion();
Conversion(std::vector <std::string>);
~Conversion();
std::vector<std::string> getLines();
bool readFile(std::string);
private:
std::vector<std::string> lines;
std::string line;
std::ifstream file;
};
#endif
Once again, Conversion text(); is a function declaration, not a class instantiation. To call the default constructor, change it to Conversion text;
You probably wanted to copy the passed lines in your constructor:
Conversion::Conversion(std::vector<std::string> const& lines) : lines(lines) { }
Your code should work now, but there can be done some improvements. To avoid copy, getLines should return by reference-to-const:
std::vector<std::string> const& getLines();
// you don't have to create lines in main, you can print like this:
for(auto const& x : text.getLines())
cout << x << endl;
and I'd use it even here:
bool readFile(std::string const&);
I hope this is the last thing - std::ifstream constructor and open function also take std::string:
file.open(filename);
You need to remove the parentheses when instantiating the Conversion object:
Conversion text;
See this question for detailed answers: Is no parentheses on a constructor with no arguments a language standard?

How to convert class object to json string using boost library in C++?

I am fairly new to C++ and I apologise beforehand if you find this very easy.
I have the following files
POST1.h
#ifndef POST1_HH
#define POST1_HH
#include <iostream>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
using namespace std ;
using boost::property_tree::ptree;
using boost::property_tree::read_json;
using boost::property_tree::write_json;
using boost::property_tree::basic_ptree;
#include "DBAccess2.h"
class POST1
{
public:
string TokenNo;
string CommandStatus;
string CommandID;
string CPUID;
string ISEncrypted;
string JSON_Cmnd_String;
void POST_Device_Status(sqliteDB & DB_OBJ);
};
#endif
Below is POST1.cpp
#include <iostream>
#include <sstream>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include "DBAccess2.h"
#include "POST1.h"
using namespace std ;
using boost::property_tree::ptree;
using boost::property_tree::read_json;
using boost::property_tree::write_json;
using boost::property_tree::basic_ptree;
void POST1::POST_Device_Status(sqliteDB & DB_OBJ)
{
POST1 POST_OBJ;
POST_OBJ.TokenNo = "1122";
POST_OBJ.CommandStatus = "0";
POST_OBJ.CommandID = "00";
POST_OBJ.CPUID = "A1234B1234";
POST_OBJ.ISEncrypted = "0";
POST_OBJ.JSON_Cmnd_String = DB_OBJ.dump(DB_OBJ);
}
NOTE:-
(1) sqliteDB is another class declared in a .cpp file.
(2) the output of function dump() is a json string. this get stored into JSON_Cmnd_string.
So, I want to convert the class object into JSON string, How can I do that ?
Do I have to first put these object into a container (like vector or list) and then write it into JSON?
This is not "fairly easy", because C++ doesn't have JSON support.
Neither does Boost:
how to get boost json to use the correct data types
That said, this appears to be what you want:
http://www.boost.org/doc/libs/1_57_0/doc/html/boost_propertytree/tutorial.html
So, I want to convert the class object into JSON string, How can I do that ? Do I have to first put these object into a container (like vector or list) and then write it into JSON?
Yes, you put them into a tree container, namely boost::property_tree::ptree:
Live On Coliru
#include <boost/property_tree/json_parser.hpp>
#include <boost/property_tree/ptree.hpp>
#include <iostream>
#include <sstream>
using boost::property_tree::ptree;
namespace Entities {
struct POST1 {
std::string TokenNo;
std::string CommandStatus;
std::string CommandID;
std::string CPUID;
std::string ISEncrypted;
};
std::string to_json(POST1 const& o) {
ptree out;
out.put("POST1.TokenNo", o.TokenNo);
out.put("POST1.CommandStatus", o.CommandStatus);
out.put("POST1.CommandID", o.CommandID);
out.put("POST1.CPUID", o.CPUID);
out.put("POST1.ISEncrypted", o.ISEncrypted);
std::ostringstream oss;
boost::property_tree::write_json(oss, out);
return oss.str();
}
}
// ADL trigger; `using Entities::to_json` would be roughly equivalent, but not
// make it clear that ADL is happening
void to_json();
int main() {
Entities::POST1 obj { "1122", "0", "00", "A1234B1234", "0" };
std::cout << to_json(obj);
}
Output:
{
"POST1": {
"TokenNo": "1122",
"CommandStatus": "0",
"CommandID": "00",
"CPUID": "A1234B1234",
"ISEncrypted": "0"
}
}
with boost 1.78.0,you can use this
use this simple way
pt::ptree root;
root.put("POST1 .TokenNo", "1122");
root.put("POST1 .CommandStatus", "0");
root.put("POST1 .CommandID", "00");
root.put("POST1 .CPUID", "A1234B1234");
root.put("POST1 .ISEncrypted", "0");
// Once our ptree was constructed, we can generate JSON on standard output
pt::write_json(std::cout, root);
OUT PUT
{
"POST1": {
"TokenNo": "1122",
"CommandStatus": "0",
"CommandID": "00",
"CPUID": "A1234B1234",
"ISEncrypted": "0"
}
}