I got a structure
struct number{
int value;
};
number numbers[1000];
I have a for loop to input the values and breakoff when the user decides to leave adding panel, that feature works fine. I got another for loop for displaying the entered data which does the job (kind of) as it requires me to use system("pause"); otherwise the loop constantly enters everything within the function including the couts that are outside of the loop.
void ListNumbers(){
system("cls");
cout << "\t\t\tArray: Numbers" << endl;;
cout << "Value" << endl;
for (int i = 0; i < 1000; i++){
if (NULL == numbers[i].value)
break;
cout << numbers[i].value << endl;
}
cout << "\n\nAmount of records: " << sizeof(numbers) / sizeof(numbers[0]) << endl;
system("pause");
I want the program to list the amount of records/indexes in the table that are currently filled with data. Currently it displays the total amount of records in the database (being 1000). Also if possible, method for fixing the display loop so I am not required to use the system pause would be extremely appreciated.
You should not be checking integer value check as :
if (NULL == numbers[i].value)
have a well defined intention like :
if (0 == numbers[i].value)
Use std::vectors for creating dynamic array, do not restrict yourself to size of 1000.
And statement :
cout << "\n\nAmount of records: " <<sizeof(numbers) / sizeof(numbers[0])
You are taking sizeof numbers array divided by sizeof 1st numbers element. This division is constant and will only vary depending sizeof(int).
For starters, you break out of the loop after finding the first NULL which is inconsistent with what you've said that you want. You should be incrementing a counter for each non-NULL value by using an if..else. You don't want to break because you want the loop to check every single entry within the table. In the cout outside of the loop, you display the counter that you have been incrementing. You can use some basic math to determine the count of NULL variables. Your use of the sizeof seems strange since you already know that the array is 1000. That is just a fancy way of producing the number 1000 which you could have just stored within a constant and reused.
I cannot understand why you think that you need a system pause. I cannot see the rest of the program so I assume that you want to pause before the console window closes. Well you could just start a command prompt and simply run the exe from a cmd window. Then it won't close. It closes because when you run from the debugger, the IDE will close the console after it finishes running the program. Depending on your IDE, there may be a solution for that but you need to tell us what IDE that you are using or just google search the issue with that IDE name within your search.
As I understand it, you want the following:
Output the valid items.
Count the valid items.
Count all the items.
I would typically implement what I think you want like this:
#include <iterator>
#include <algorithm>
#include <iostream>
struct number
{
int value;
};
std::ostream& operator << ( std::ostream& os, const number& n )
{
return os << n.value;
}
number numbers[] = { {1}, {0}, {2}, {0}, {3}, {0}, {4}, {0} };
template <class T, std::size_t N>
T* begin( T (&array)[N] )
{
return array;
}
template <class T, std::size_t N>
T* end( T (&array)[N] )
{
return array+N;
}
template <class T, std::size_t N>
std::size_t itemCount( T (&array)[N] )
{
return N;
}
bool is_zero( const number& n ){ return( n.value == 0 ); }
bool is_not_zero( const number& n ){ return( !is_zero( n ) ); }
void listNumbers()
{
std::cout << "Valid values are:" << std::endl;
std::remove_copy_if( begin( numbers ), end( numbers ),
std::ostream_iterator<number>(std::cout, "\t" ), is_zero );
std::cout << std::endl;
std::iterator_traits<number*>::difference_type count =
std::count_if( begin( numbers ), end( numbers ), is_not_zero );
std::cout << "There is " << count
<< " items with valid values out of a possible sequence of "
<< itemCount( numbers ) << "." << std::endl;
}
int main( int argc, char* argv[] )
{
listNumbers();
return 0;
}
I've thrown in a couple of typical c++ concepts that you might consider e.g the use of standard algorithms to do the work for you. I would personally use a vector instead of an array, and binders with member functions (or a lambda) to check whether values are not zero (or visa versa), but I've used the array and some non member functions for you to get the idea.
Related
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.
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.
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.
I'd like to simulate a std::vector that has mixed const and non-const elements. More specifically, I want to have functions that operate on a vector and are allowed to see the entire vector but may only write to specific elements. The elements that can and cannot be written will be determined at runtime and may change during runtime.
One solution is to create a container that holds an array of elements and an equal sized array of booleans. All non-const access would be through a function that checks against the boolean array if the write is valid and throws an exception otherwise. This has the downside of adding a conditional to every write.
A second solution might be to have the same container but this time write access is done by passing an array editing function to a member function of the container. The container member function would let the array editing function go at the array and then check that it didn't write to the non-writable elements. This has the downside that the array editing function could be sneaky and pass around non-const pointers to the array elements, let the container function check that all is well, and then write to non-writable elements.
The last issue seems difficult to solve. It seems like offering direct writable access ever means we have to assume direct writable access always.
Are there better solutions?
EDIT: Ben's comment has a good point I should have addressed in the question: why not a vector of const and a vector of non-const?
The issue is that the scenario I have in mind is that we have elements that are conceptually part of one single array. Their placement in that array is meaningful. To use vectors of const and non-const requires mapping the single array that exist in concept to the two vectors that would implement it. Also, if the list of writable elements changes then the elements or pointers in the two vectors would need to be moved about.
I think you can accomplish what you wish with the following class, which is very simplified to illustrate the main concept.
template <typename T>
struct Container
{
void push_back(bool isconst, T const& item)
{
data.push_back(std::make_pair(isconst, item));
}
T& at(size_t index)
{
// Check whether the object at the index is const.
if ( data[index].first )
{
throw std::runtime_error("Trying to access a const-member");
}
return data[index].second;
}
T const& at(size_t index) const
{
return data[index].second;
}
T const& at(size_t index, int dummy) // Without dummy, can't differentiate
// between the two functions.
{
return data[index].second;
}
T const& at(size_t index, int dummy) const // Without dummy, can't differentiate
// between the two functions.
{
return data[index].second;
}
std::vector<std::pair<bool, T> > data;
};
Here's a test program and its output.
#include <stdio.h>
#include <iostream>
#include <utility>
#include <stdexcept>
#include <vector>
//--------------------------------
// Put the class definition here.
//--------------------------------
int main()
{
Container<int> c;
c.push_back(true, 10);
c.push_back(false, 20);
try
{
int value = c.at(0); // Show throw exception.
}
catch (...)
{
std::cout << "Expected to see this.\n";
}
int value = c.at(0, 1); // Should work.
std::cout << "Got c[0]: " << value << "\n";
value = c.at(1); // Should work.
std::cout << "Got c[1]: " << value << "\n";
value = c.at(1, 1); // Should work.
std::cout << "Got c[1]: " << value << "\n";
// Accessing the data through a const object.
// All functions should work since they are returning
// const&.
Container<int> const& cref = c;
value = cref.at(0); // Should work.
std::cout << "Got c[0]: " << value << "\n";
value = cref.at(0, 1); // Should work.
std::cout << "Got c[0]: " << value << "\n";
value = cref.at(1); // Should work.
std::cout << "Got c[1]: " << value << "\n";
value = cref.at(1, 1); // Should work.
std::cout << "Got c[1]: " << value << "\n";
// Changing values ... should only work for '1'
try
{
c.at(0) = 100; // Show throw exception.
}
catch (...)
{
std::cout << "Expected to see this.\n";
}
c.at(1) = 200; // Should work.
std::cout << "Got c[1]: " << c.at(1) << "\n";
}
Output from running the program:
Expected to see this.
Got c[0]: 10
Got c[1]: 20
Got c[1]: 20
Got c[0]: 10
Got c[0]: 10
Got c[1]: 20
Got c[1]: 20
Expected to see this.
Got c[1]: 200
I have a command line C++ program that lets you enter basic information about a person (ID number, name, age, etc.) and I want to output to a console in the following manner:
-------------------------------------------------------------------
Index ID # First Name Last Name Age
-------------------------------------------------------------------
0 1234 John Smith 25
The person objects are stored in an array of Persons and I've overload the ostream (<<) operator to print out all of the fields like you see. The dashed lines and header come from a displayHdg() function. Anyhow, I have not been able to figure out how to get the proper index value for the array. Ideally, I'd like to generate the indices for each line, but all my attempts have failed. The array is looped through and each object printed in the main() function, and the ostream is overloaded in a person class, so I tried to use global variables as well as static variables, and all of those produce incorrect numbering (i.e. show 0, 1 the first time (for 2 objects), then change to 1, 2 on the next display). Any ideas?
Wouldn't this work? (formatting of ID field ommitted)
vector<Person> v;
for (int i = 0; i < v.size(); ++i)
cout << i + 1 << v[i] << endl;
This starts indexing at 1.
EDIT:
OK now I see what you want. You want to find an element in the vector!
std::vector<person>::iterator p =
std::find(Persons.begin(), Persons.end(), element);
if( p != Persons.end() )
{
std::cout << "index of element is: " << p-Persons.begin();
}
If you have the correct formating, you should be able to do the following:
for(size_t i = 0; i < Persons.size(); ++i)
{
cout << i << '\t' << Persons[i] << endl;
}
I would recommend taking a look at the formatting facilities in brief in this post. Using setw, left, right... manipulators is better than doing it manually.
You need to use "find" algorithms to find exact index of Person object in vector < Person>.
You could use wrapper class to hold index and print it according to your formatting in operator<<:
// wrapper to hold index
template<typename T>
struct Ti
{
Ti( size_t index, const T& t ) : index(index), val(t) {}
size_t index;
const T& val;
};
// you class
struct X
{
friend ostream& operator<<( ostream& out, Ti<X>& t );
protected:
int some_data;
};
// operator<< for X
ostream& operator<<( ostream& out, Ti<X>& t )
{
out << "test " << t.index << " " << t.val.some_data;
return out;
}
int main()
{
vector<X> xxx;
for ( size_t i =0; i < xxx.size(); ++i)
cout << Ti<X>(i+1, xxx[i]) << endl;
}