Hi, I need a way of storing many streams of data in buffers. I will be getting real time temperature data from many cities through a socket. For each city, I will be storing the newest 20 data points in a circular buffer. Each time any buffer updates, I need to be able to access each element in the buffer. The boost circular buffer allows random access, so I think it's suitable. I have a .txt file listing all the cities. First, my program counts how many cities there are and stores each city name in a stl vector of strings. Then I create a stl deque that has a slot for each city. I want to load each slot in the deque with a boost buffer. The name of the i'th buffer should be the i'th item in the string vector, i.e the name of the i'th city. My problem is, I don't know how to fit the buffers within the deque, or if that's even possible. Note: as far as speed is concerned, I don't plan on overwriting/adding buffers very often at all, it's the numbers within the buffers that will be updated often. Here's what I have so far:
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include <deque>
#include <boost/circular_buffer.hpp>
usingnamespace std;
int main()
{
std::fstream file("capitals.txt");
std::string x;
// Creates a vector to hold all the names of the buffers.
vector<string> lines (0);
/*
Gets each line, counts the number of lines, and loads vector with each line.
"push_back" increments the size of the vector up from 0, and then loads the vector.
*/
while (getline(file, x))
{
lines.push_back(x);
}
for (int i = 0; i < lines.size(); i++)
cout << " " << lines.at(i) << '\n';
// Outputs the number of lines.
std::cout << " Number of cities: " << lines.size() << "." << std::endl;
// Creates a deque of size = number of lines. What should the data type be???
deque<int> allcapitals (lines.size());
// Filling each slot in the deque with circular buffers. The name of
// the nth circular buffer should be the nth line from capitals.txt.
for (int i = 0; i < lines.size(); i++)
{
allcapitals.at(i) = boost::circular_buffer<double> lines.at(i)(20);
}
return 0;
}
Looking at your code, I believe that you want to generate object identifiers at run-time - a feature C++ does not have.
What you can do is to use a map, like this (not tested):
1 2 3 4 5 6
map<string,boost::circular_buffer<double>*> allcapitals ();
for (int i = 0; i < lines.size(); i++)
{
allcapitals.insert(make_pair(lines[i], new boost::circular_buffer<double>(20)));
}
make_pair requires <utility>, map requires <map> (of course). Remember to delete the dynamically allocated circular buffers once you are done with them, or they will linger in memory until the program terminates.
int main()
{
std::fstream file("capitals.txt");
std::string x;
vector<string> lines (0);
while (getline(file, x))
{
lines.push_back(x);
}
for (int i = 0; i < lines.size(); i++)
cout << " " << lines.at(i) << '\n';
std::cout << " Number of cities: " << lines.size() << "." << std::endl;
map<string,boost::circular_buffer<double>*> allcapitals ();
for (int i = 0; i < lines.size(); i++)
{
allcapitals.insert(make_pair(lines[i], new boost::circular_buffer<double>(20)));
}
return 0;
}
I get an error:
"left of '.insert' must have class/struct/union". I guess somehow I need to turn the buffer into a class so the map can recognize it? Do you know how to deal with this?
Sorry, remove the parenthesis after allcapitals. That's the oldest trap in C++ and I just fell in it. When I tried to define allcapitals, I actually introduced non-parametrized function returning map. It is just language idiosyncrasy.
If you turn: map<string,boost::circular_buffer<double>*> allcapitals ();
into map<string,boost::circular_buffer<double>*> allcapitals;
that should get fixed.