Stream object that handles numbers - c++

This may be a very basic question but while digging through STL reference I can't find anything suitable. As an example
std::ostringstream oss;
oss << "One hundred and one: " << 101;
would result in One hundred and one: 101 stored in oss, means the numeric value 101 is converted to text. What I'm looking for is a stream object that keeps the numeric value so that something like:
numstream nums;
nums << 10 << 0 << 15;
would result in a byte or string buffer containing not a textual representation of 10, 0 and 15 but just these three numbers.
Any idea what could be used for this?

A buffer containing a sequence of integers is what std::vector<int>
controls.
You can override the global operator << to append
any type T to any container type C for which such an operation is
meaningful:
#include <vector>
#include <iostream>
std::vector<int> & operator<<(std::vector<int> & vi, int i)
{
vi.push_back(i);
return vi;
}
int main()
{
std::vector<int> vi;
vi << 1 << 2 << 3;
for(auto i : vi) {
std::cout << i << std::endl;
}
return 0;
}
However, if all you want to achieve is an abbreviation of, e.g.
si.push_back(i);
for some integer sequence si and int i, and to be able to shorten, e.g.
si.push_back(i);
si.push_back(j);
si.push_back(k);
to:
si << i << j << k;
remember that the brevity you gain comes at the cost of
making otherwise skilled readers research what your abbreviations are -
and how safe they are.
I suggest that shortening si.push_back(i) to si << i is not worthwhile
and that if you want to get tiresomely long sequences of push_back(n) onto
one line then it would be sufficient and less eccentric to define
a type-safe variadic function template for the purpose, e.g.
void push_back(std::vector<int> & vi){}
template<typename ...Ts>
void push_back(std::vector<int> & vi, int i, Ts... ts)
{
vi.push_back(i);
if (sizeof...(Ts)) {
push_back(vi,ts...);
}
}
With which you would write, e.g.
push_back(si,i,j,k);
rather than:
si << i << j << k;

With this semantic (stream insertion): no there isn't.
From your example it looks like you want to fill a vector of integers with integers.
You will need a functor (ostream manipulator) which would translate the ostream-like semantics into vector-element-addition.
Something along the lines of:
struct functor {
functor(std::vector<int>& viref):
myVector(viref)
{}
// this operator overload translates stream-insert operator
// into vector element addition
functor& operator<<(const int i) {
myVector.push_back(i);
return *this;
}
std::vector<int>& myVector;
};
int main() {
std::vector<int> vi;
functor f( vi );
f << 1 << 2 << 3;
}
Alternatively, you could always write your own streambuffer class (http://www.cplusplus.com/reference/streambuf/streambuf/) but I doubt that that will go down very well because the whole string/stream buf mechanism really is meant to be dealing with single characters being inserted/removed.

Related

Binary analog of std::dec, std::hex, std::oct

I noticed that although the standard library has I/O manipulators to print numbers in either decimal, hexadecimal, or octal form (std::dec, std::hex, std::oct), it does not have one for binary.
How would I go about implementing an analogous binary I/O manipulator?
Anti-duplicate-marking section: I am quite dissapointed that I have to do this, but my questions almost always get marked as duplicates of completely different and unhelpful questions. Perhaps this will help people stay away from false duplicates and find the real duplicates, if they do exist.
I know how to print a number's binary representation. That is a trivial task for anyone who knows how numbers are stored in a computer, and not the purpose of this question (i.e. implementing std::string to_binary(T value), void print_binary(T value), ...).
I know that it is easy for anyone who has memorized the hexadecimal values to convert from hex to binary in their head. But any time you introduce human work, you introduce human capacity for error. Always best to avoid it if possible.
I realize there are rules about what you are allowed to do with respect to extending the standard library, though I don't know the inner workings of streams and manipulators well enough to know exactly what's allowed in this case. I'm not looking for a cop-out "you can't do that" answer - if the exact analog can't be created, then give me the cleanest allowed solution you can think of that is allowed.
Here is what I have thrown together so far, it still has many problems and I don't really understand what is going on. I have just copied and modified the solution to the question Phil linked.
#include <ios>
#include <iostream>
#include <locale>
int geti() {
static int i = std::ios_base::xalloc();
return i;
}
std::ostream& bin_manip(std::ostream& os) {
os.iword(geti()) = 1;
return os;
}
std::ostream& dec_manip(std::ostream& os) {
os.iword(geti()) = 0;
return os;
}
struct my_num_put : std::num_put<char> {
iter_type do_put(iter_type out, std::ios_base& str, char_type fill, long v) const {
bool binary_flag = str.iword(geti());
if (binary_flag) {
size_t width = 8 * sizeof(v);
for (size_t i = width - 1; i < width; --i) {
long bit = (((1 << i) & v) >> i) & 1;
out = std::num_put<char>::do_put(out, str, fill, bit);
}
return out;
}
else {
return std::num_put<char>::do_put(out, str, fill, v);
}
}
/*
iter_type do_put(iter_type s, std::ios_base& f, char_type fill, unsigned long v) const {
return std::num_put<char>::do_put(s, f, fill, v + f.iword(geti()));
}
*/
};
int main() {
std::cout.imbue(std::locale(std::locale(), new my_num_put)); // memory leak?
int v1 = 10;
long v2 = 11;
std::cout << bin_manip << v1 << std::endl << v2 << std::endl;
std::cout << dec_manip << v1 << std::endl << v2 << std::endl;
return 0;
}
The output is the following:
0000000000000000000000000000000000000000000000000000000000001010
0000000000000000000000000000000000000000000000000000000000001011
10
11
The main problem I see here is code duplication when dealing with various types. As is, I just worked with the do_put function that takes a value of type long, which unfortunately prints out int values much wider than they should be. I tried to template the function and it nullified the effect of the manipulator entirely, simply printing out 10 and 11 rather than their binary representations.
Another issue is that I'm not sure what the best way to write each 1 and 0 to the stream is. For now I am writing them as longs which seems problematic, I'd really want to write them as single characters.
Finally, I'm not sure if the new is creating a memory leak, but valgrind is telling me it doesn't.
You could refer to this https://en.cppreference.com/w/cpp/io/manip/hex
// Note: there is no I/O manipulator that sets up a stream to print out
// ` numbers in binary format (e.g. bin). If binary output is necessary
// ` the std::bitset trick can be used:
std::cout << "The number 42 in binary: " << std::bitset<8>{42}
<< std::endl;
// output : The number 42 in binary: 00101010

Array like data structure with negetive index in C++

I need a structure to keep track of presence of some items. I just wanted to take an array a0....aN and mark the elements as a[0]=0,a[1]=0,a[2]=1........(a[i]=1 if the element is present,a[i]=0 if element is not present).
But the items range from -1000 to +1000. It can be done by putting the negative range from 1001 to 2000. I needed to know if there is any other data structure in c++ that can work like array and with negative indexes. Thank you for your time.
map is used for this only, to have key/index of any basic/user-defined data type. See - http://www.cplusplus.com/reference/map/map/
Example for your case:
#include <iostream>
#include <map>
#include <string>
int main ()
{
std::map<int, int> mymap;
mymap[-1]=1;
mymap[-2]=0;
mymap[-3]=1;
std::cout << mymap[-1] << '\n';
std::cout << mymap[-2] << '\n';
std::cout << mymap[-3] << '\n';
return 0;
}
Example for char:
#include <iostream>
#include <map>
#include <string>
int main ()
{
std::map<char,std::string> mymap;
mymap['a']="an element";
mymap['b']="another element";
mymap['c']=mymap['b'];
std::cout << "mymap['a'] is " << mymap['a'] << '\n';
std::cout << "mymap['b'] is " << mymap['b'] << '\n';
std::cout << "mymap['c'] is " << mymap['c'] << '\n';
std::cout << "mymap['d'] is " << mymap['d'] << '\n';
std::cout << "mymap now contains " << mymap.size() << " elements.\n";
return 0;
}
You an create your own data structure which supports -ve indexes. Just add an offset to the indexs while storing them in an array.
class MyArray {
int *arr;
public:
MyArray(int offset) {
arr = new int[2*offset]; // size must to double the offset
}
~MyArray(){
delete arr;
}
void add(int index, int val) {
arr[index + offset] = val;
}
void get(int index) {
return arr[index + offset];
}
}
Then you can just use your class to add and get elements with any index.
MyArray arr = MyArray(1000); // pass max -ve index as offset
arr.add(10, -150);
cout << arr.get(100);
I need a structure to keep track of presence of some items.
If what you want is set semantics, use a set data structure.
No need to implement a custom array wrapper.
You can use a std::set (or std::unordered_set) for that. Remember that "premature optimization is the root of all evil".
Insert the values that are there, leave out the values that are missing. No need to worry about negative indices.
You can use the methods std::set::find() or std::set::count() to check the presence of an item. Have a look at the documentation to find some example code.
If you later find it's a performance critical optimization, you can replace a std::set<int> with a data structure that you wrote yourself on the basis of an array of bits anytime. If it's not, doing so prematurely might turn out to be an unnecessary source of unexpected errors and a waste of time.
For reference:
http://en.cppreference.com/w/cpp/container/set
http://en.cppreference.com/w/cpp/container/unordered_set
http://en.cppreference.com/w/cpp/container/set/find
http://en.cppreference.com/w/cpp/container/set/count
How to check that an element is in a std::set?
Most efficient approach will be just shifting your array indexes so all of them are non-negative. In your case just use a[i+1000] and it will be sufficient.
If you really need to use negative indexes it is also possible.
C / C++ calculates memory address of array element using address of table and then adding index value to it. Using negative numbers just points to memory area placed before your table (which is not you normally want).
int a[2001];
int *b = &a[1000];
int x = b[-1000]; // This points to 1000 places before b which translates to a[0] (valid place)
Another approach will be using containers. Then any number can be translated to string and stored in proper container.
I think that the answer of #Rajev is almost fine. I have just replaced a plain array with a std::vector. Thus, the memory management is secure and copying and moving is easy.
template <typname T>
class MyArray {
private:
std::vector<T> arr;
public:
MyArray(int offset) {
arr.resize(2*offset); // size must to double the offset
}
void set(int index, int val) {
arr[index + offset] = val;
}
void get(int index) {
return arr[index + offset];
}
}
You can expand this further by overloading the operator [] of MyArray.

Container Class vs Class - C++

I'm new to programming and just come across this assignment
Create a container class family that holds an array of 20 person objects.
I have been looking on the internet as well as in my book, but I still can't figure out the difference between a Container Class and a Class in C++.
How could I create a family class and 20 person objects at the same time?
"Container class" is not some official term; it's just the word "class" with an English describing word next to it. The assignment is asking you to create a class that contains some other stuff; namely, an array of 20 person objects.
At its most basic, the result could be as simple as this:
class family
{
public:
person people[20];
};
In real life, you might do something like this instead:
#include <array>
using family = std::array<person, 20>;
It seems unlikely that every family (or even most families) has precisely 20 people in it, so I would personally end up just going with:
#include <vector>
std::vector<person> family;
… and manipulating the vector as appropriate.
C++ is an object oriented language that encourages you to "encapsulate". The first step of this is to group concepts into objects described in terms of their data values and the operations that can be performed on that data.
So one could define an Account class consisting of an id and balance and functions to deposit or withdraw currency. This definition forms the type, but when you "instantiate" (create an instance of) this type, i.e.
Account a;
then the variable a refers to an object of type Account in this scope.
Sometimes you need a class that can store and track objects of other types. This is what is sometimes referred to as a "container class" and typically it combines a store and a count.
Say we want to store some floats. We could just write:
float store[64];
std::cout << "Enter the first number: ";
std::cin >> store[0];
But how would we track how many floats we have? We would probably need a counter.,
float store[64];
int stored = 0;
std::cout << "Enter the first number: ";
std::cin >> store[0];
stored++;
std::cout << "Enter the second number: ";
std::cin >> store[1];
stored++;
This works, and it's not terribly difficult, but if you are writing a function that expects to take a store and it's size, how do you express that?
void myFunction(std::string label, float* store, int count);
This requires two arguments and it's not exactly explicit.
C++ is about encapsulation: this idea of a "store" with a count of the contents could be encapsulated into a class:
struct Store {
float store_[64] {};
int count_ {0};
};
this is a container. We can now write our function that takes an object that contains other values with a single parameter:
void myFunction(std::string label, Store& store); // & here = by reference
If this was 'C' you would write code that directly manipulated the values in the store:
store.store_[N] = 1;
store.count_++;
but that's messy, we didn't check there was room. In C++, we can encapsulate this into the class description with member functions and hide the member variables so that you have to go through our proscribed interface to manipulate the data.
#include <iostream>
class Store {
enum { MaxCount = 64 };
float store_[MaxCount] {};
size_t count_ = 0;
public:
// return the maximum number of elements we can store
size_t capacity() const { return MaxCount; }
// true/false: is the store empty?
bool empty() const { return count_ == 0; }
// return the current count
size_t size() const { return count_; }
bool add(float value) {
if (count_ >= capacity()) {
std::cerr << "store is full!\n";
return false;
}
store_[count_] = value;
++count_;
}
// reset
void clear() {
count_ = 0; // we don't actually need to change the store
}
// allow array-like usage
const float& operator[](size_t index) const { return store_[index]; }
float& operator[](size_t index) { return store_[index]; }
// provide bounds-checked array-ish access
float at(size_t index) const {
if (index >= count_)
throw std::invalid_argument("array index out of bounds");
return store_[index];
}
};
int main() {
Store store;
for (size_t i = 0; i < store.capacity(); ++i) {
std::cout << "Enter number #" << i << " or -ve to stop: " << std::flush;
float f = -1;
std::cin >> f;
std::cout << "\n" << f << "\n";
if (f < 0)
break;
store.add(f);
}
std::cout << "You entered " << store.size() << " values:";
for (size_t i = 0; i < store.size(); ++i) {
std::cout << ' ' << store[i];
}
std::cout << '\n';
}
Live demo: http://ideone.com/boE3Ki
They are telling you to create a class that acts as a container for an array. In programming, especially when you first start, you will see many elements called containers because your teacher wants you to view variables, classes, and arrays (among other programming tools) as containers for you to store data in.
Viewing programming this way makes is much easier to conceptualize information as you get into more complex ideas like pointers.
So, long answer short, create a class with the array inside it. If you are learning about constructors and overloading make sure you are initializing it based on the data you pass in. If not, it should be only a couple lines of code to complete the project.

Using an array in a for loop - C++

I want to set a test condition to determine the size of an array, and then move through each value of the array in a for loop.
Take this array for example
std::string expenses[] = {"housing", "utilities", "household expenses", "transportation", "food", "medical", "insurance", "entertainment", "clothing", "misc"};
The brackets are empty, and there are 10 elements in there. How would you create a for loop for this without creating a separate variable that holds an int of 10?
Use the countof macro, declared like this:
#define countof(a) (sizeof(a)/sizeof((a)[0]))
so you can say:
for (i = 0; i < countof(expenses); i++) ...
As everybody's pointing out, you gotta be a good enough hot-shot to know the difference between an array and a pointer.
If you pass a pointer to expenses, of course, countof will be bogus.
My immediate inclination would be to tell you to use a vector instead of an array. With a vector, you can get the size quite easily, and (better still) avoid getting the size by using a range-based for loop:
std::vector<std::string> expenses {"housing", "utilities", "household expenses", "transportation", "food", "medical", "insurance", "entertainment", "clothing", "misc"};
// print out the strings, one per line:
for (auto const &s : expenses)
std::cout << s << "\n";
If you really have to use an array instead of a vector, you can use a function template to compute the size:
template <class T, size_t N>
size_t size(T (&array)[N]) {
return N;
}
for (int i=0; i<size(expenses); i++)
std::cout << expenses[i] << '\n';
The primary advantage of this template function over the usual macro ((sizeof(x)/sizeof(x[0]))) is that it's strongly typed--any attempt at passing a pointer instead of an array simply won't compile (and given how easy it is for an array's name to decay to a pointer, that's significant).
If you have C++11 available, you can use the std::begin and std::end from the standard library to accomplish (roughly) the same:
for (auto s = std::begin(expenses); s != std::end(expenses); ++s)
std::cout << *s;
Note that although std::begin and std::end were added in C++11, you can use code similar to the size template above to create similar templates for a C++98/03 compiler.
template <class T, size_t N>
T *begin(T (&array)[N]) {
return array;
}
template <class T, size_t N>
T *end(T (&array)[N]) {
return array + N;
}
These can also be used with standard algorithms, so you could do something like this:
std::copy(begin(expenses), end(expenses),
std::ostream_iterator<std::string>(std::cout, "\n"));
Again, note that we've avoided dealing directly with the count or creating subscripts into the array, and just deal with iterators into the array, and the items to which those iterators refer.
If you mean to run through each element (within the same scope), then 'The Dark' is correct:
#include <string>
#include <iostream>
int main()
{
std::string expenses[] = {"housing", "utilities", "household expenses", "transportation", "food", "medical", "insurance", "entertainment", "clothing", "misc"};
std::cout<< "NumEls = " << sizeof(expenses) / sizeof(expenses[0]) << std::endl;
}
produces an output of 10, and replacing the cout with a for loop would allow testing of the strings, for example
for (int i=0; i< (sizeof(expenses)/sizeof(expenses[0])); i++)
{
std::cout<< "The " << i << "th string is : " << expenses[i] << std::endl;
}
Note this will produce "0th", "1th", etc...
* Caveat *
Reflecting the comments given in the question, our answers seem incomplete without mention of the fact that the sizeof(POINTER) won't give you useful information - or at least, not useful for this. As such, if you want instead to use:
myFunction (std::string someArray[])
{
for( all the strings in someArray )
{
std::cout << someArray[i];
}
}
then you'll find yourself unable to do so.
Instead, you could use:
myFunction (std::string someArray[], int sizeOfArray)
{
for(int i=0; i<sizeOfArray; i++)
{
std::cout<< someArray[i];
}
}
but this goes exactly against your question (not storing a separate int)
* Enter std::vector *
A simpler solution is to use a std::vector
The use of a vector allows function calls such as myVector.size() and also loops based automatically on the size of the vector, in the case of more recent (C++11) compilers/compiler options.
Vectors can be happily passed into and out of functions, and if you want to change them, references to vectors are also a simple way to do so - referring to your answer:
inputFunction (std::vector<string> &expenses, budget &info)
{
for (int i=0; i< expenses.size(); i++)
{
std::cout<< "Enter your expense for " << expenses[i] << ": ";
// Operation to store input as needed
}
}
On a side note, it seems like you want to link the string for the name of the expense to the value of the expense? If so, consider perhaps using a map. In this case, you'd probably want to consider std::map<std::string, float>.
* Using a std::map *
In using a map, you'll probably want an iterator. An example might be like:
void input(const std::vector<std::string> &exp, std::map<std::string, float> &map)
{
for (int i=0; i<exp.size(); i++)
{
float tempFloat;
std::cout<< "Please enter the amount for " << exp[i] << ": ";
std::cin >> tempFloat;
map.emplace(exp[i], tempFloat);
}
};
and in main(),
std::map<std::string, float> myMap;
input(myVec, myMap);
for (std::map<std::string, float>::iterator it=myMap.begin(); it!=myMap.end(); it++)
{
std::cout << "myMap values -> " << it->first << " = " << it->second << std::endl;
}
This will output each pair you have, using an iterator starting at myMap.begin() and ending at the last entry to your map.
emplace(...) constructs a pair, and then adds it to the map. You should take care not to use insert, which requires a different set of parameters, and is not likely to be what you want here.
The outputs are referenced by iterator->first and iterator->second, the first and second values of each map pair. In this case, those are the string and float that are stored in the map.
You can use sizeof(expenses) / sizeof (expenses[0]). Note that you don't need the brackets, but I prefer it.
A number of people have mentioned the (sizeof(expenses)/sizeof(expenses[0])) trick, but if you're going to go that route, in C++ there is a slightly better way to do it using a templated function:
/* returns # of items in array, or will error out at compile time if you try to pass it a pointer instead of an array */
template<typename T, int size> unsigned int array_size(T(&)[size]) {return size;}
This is safer, since it will give you a compile-time error if you accidentally pass in a pointer rather than an array. (The sizeof() version would compile and then do something unexpected at runtime, which is undesirable)
Two possibilities. If you want to iterate over it in the same scope that you define it, you can simply use a ranged based for loop:
for(auto& expense : expenses)
{
std::cout << expense << std::endl;
}
If you want to be able to pass it to a function, you'd have to to some ugly stuff to fit it into a std::array, then you can use the above range loop on it anywhere.

Is it possible to print vector content with width of 5?

Here is what I have to do!
Write a program to perform the following steps.
Allocate memory dynamically to store an array of 10 ints.
Assign each int a random value between 1 and 100.
Copy each of the 10 random ints to a vector of ints.
Print the dynamically allocated array of ints and the vector of ints, each with a width of 5, as shown in the sample output below.
I have trouble with the last point. My code is working perfectly, but I don't know how to set width in vector of ints so it is the same as array of ints.
#include<iostream>
#include<iomanip>
#include<cstdlib>
#include <vector>
#include <algorithm>
#include <iterator>
#include <stdexcept>
using namespace std;
int main(){
const int SIZE = 10;
int *arr = new int[SIZE];
//assign rand numbers between 0 and 100
for (int i = 0; i < SIZE; ++i){
*(arr + i) = rand() % 100+1;
}
//print array
for (int i = 0; i < SIZE; ++i){
cout << setw(5) << *(arr +i) << " ";
}
std::vector<int> integers (arr, arr + 10);
std::ostream_iterator<int> output(cout, " ");
cout << endl;
cout << "Vector integers contain: " << endl;
std::copy(integers.begin(), integers.end(), output);
return 0;
}
Your code works fine as is. cout << setw(5); sets the width just fine. You could also use cout.width(5);.
If you really want to do this with an ostream_iterator, the cleanest way is probably with a small proxy class:
class integer {
int i;
public:
integer(int i) : i(i) {}
friend std::ostream &operator<<(std::ostream &os, integer i) {
return os << std::setw(5) < i.i;
}
};
Then to write them out, use that type as the template parameter to the ostream_iterator:
std::copy(integers.begin(), integers.end(),
std::ostream_iterator<integer>(std::cout, ' '));
This will create a temporary integer object, then write it out using the operator<< for integer, which sets the width. At least in theory, this probably imposes some overhead, but I'd expect (at least with optimization enabled) most compilers will probably see through the subterfuge (so to speak) and eliminate any extra copies and such.
Of course, if the width isn't cast in concrete, you could make integer a template, and supply the width as a template parameter:
template <int N>
class integer {
// ...
return os << std::setw(N) < i.i;
Unless I really needed to use an ostream_iterator, I think I'd use a range-based for loop though:
for (int i : integers)
std::cout << std::setw(5) << i << ' ';
Since the width of a stream is reset to 0 everytime it is used, you can't use a std::ostream_iterator<int> (well, you could by using a custom std::num_get<char> facet which restores the width but that seems a bit radical).
You can print the std::vector<int> like this, however:
std::for_each(integers.begin(), integers.end(),
[](int v){ std::cout << std::setw(5) << v << ' '; });