I have a simple function that prints lines of text to the console, centered, with empty space filled in with an '=' sign. When I run this function with my program on Linux I see the text displayed properly at the top of the console window followed by the menu prompt from my program, but on Windows it prints nothing and skips directly to the menu prompt. Both programs are compiled and run in codeblocks using GNU gcc with -std=c++11.
void _print_center(vector<string>& tocenter)
{
int center;
for ( int x; x<static_cast<int>(tocenter.size());x++ )
{
char sfill = '=';
string line = tocenter[x];
center = (68/2)-(tocenter[x].length()/2);
line.replace(0, 0, center, sfill);
cout << std::left << std::setfill(sfill);
cout << std::setw(68) << line << endl;
}
}
You got an answer to your question (uninitialized variables). I recommend that you untangle and simplify your code so that this kind of issues don't creep up as often. For example:
Create a function that centers a single string.
void center( std::ostream& os, const std::string& text, int width ) {
if ( text.size() >= width ) {
// Nothing to center, just print the text.
os << text << std::endl;
} else {
// Total whitespace to pad.
auto to_pad = width - text.size();
// Pad half on the left
auto left_padding = to_pad / 2;
// And half on the right (account for uneven numbers)
auto right_padding = to_pad - left_padding;
// Print the concatenated strings. The string constructor will
// correctly handle a padding of zero (it will print zero `=`).
os << std::string( left_padding, '=' )
<< text
<< std::string( right_padding, '=' )
<< std::endl;
}
}
Once you've tested that the function works well for a single string, it is trivial to rely on C++ to apply it to a vector of strings:
void center( std::ostream& os,
const std::vector< std::string >& strings,
int width ) {
for ( auto&& string : strings ) {
center( os, string, width );
}
}
Whether you want to use std::string, or iomanip manipulators, or std::setfill the point remains the same: do not implement "iteration and formating" in the same function.
Related
So I have three strings and these strings are supposed to occupy 3 lines. I thought this was a good way to represent my string:
std::string str1 = "███████\n███1███\n███████";
std::string str2 = "███████\n███2███\n███████";
std::string str3 = "███████\n███3███\n███████";
But I realise that when I do this and just cout the strings, they get printed on top of each other which is not I want. I want the output to look like this:
█████████████████████
███1██████2██████3███
█████████████████████
How can I achieve this effect? I only know setw to manipulate the output however I don't know how that could help here.
note: I will have these stored in an array and than loop over the array and print them, I feel like that might change the solution a bit as well.
Store the rows of each card as elements in an array. That makes it pretty easy.
#include <iostream>
int main()
{
const char * str1[3] = {"███████","███1███","███████"};
const char * str2[3] = {"███████","███2███","███████"};
const char * str3[3] = {"███████","███3███","███████"};
for( int row = 0; row < 3; row ++ )
{
std::cout << str1[row] << str2[row] << str3[row] << "\n";
}
}
Output:
█████████████████████
███1██████2██████3███
█████████████████████
Again, pretty easy to add a space between those, if you want.
You could split each on \n and print them. We can use std::stringstream for splitting by \n.
void print(std::array<std::string, 3>& arr){
std::vector<std::stringstream> arr_buf{};
arr_buf.reserve(arr.size());
for(auto& str: arr){
arr_buf.emplace_back(str);
}
for(auto i=0u; i < arr.size(); ++i){
for(auto& stream: arr_buf){
std::string t;
stream >> t;
std::cout << t ;
}
std::cout << "\n";
}
}
Output:
print(arr)
█████████████████████
███1██████2██████3███
█████████████████████
Link to Demo
If you are certain that your output will always be displayed on a modern terminal supporting “ANSI Escape Codes” then you can use that to your advantage.
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
// helper: split a string into a list of views
auto splitv( const std::string & s, const std::string & separators )
{
std::vector <std::string_view> views;
std::string::size_type a = 0, b = 0;
while (true)
{
a = s.find_first_not_of( separators, b );
b = s.find_first_of ( separators, a );
if (a >= s.size()) break;
if (b == s.npos) b = s.size();
views.emplace_back( &(s[a]), b-a );
}
return views;
}
std::string print( const std::string & s )
{
std::ostringstream os;
for (auto sv : splitv( s, "\n" ))
os
<< "\033" "7" // DEC save cursor position
<< sv
<< "\033" "8" // DEC restore cursor position
<< "\033[B"; // move cursor one line down
return os.str().substr( 0, os.str().size()-5 );
}
std::string movexy( int dx, int dy )
{
std::ostringstream os;
if (dy < 0) os << "\033[" << -dy << "A";
else if (dy > 0) os << "\033[" << dy << "B";
if (dx > 0) os << "\033[" << dx << "C";
else if (dx < 0) os << "\033[" << -dx << "D";
return os.str();
}
int main()
{
std::string str1 = "███████\n███1███\n███████";
std::string str2 = "███████\n███2███\n███████";
std::string str3 = "███████\n███3███\n███████";
std::cout
<< "\n" "\n\n" // blank line at top + blocks are three lines high
<< movexy( 2, -2 ) << print( str1 ) // first block is placed two spaces from left edge
<< movexy( 1, -2 ) << print( str2 ) // remaining blocks are placed one space apart
<< movexy( 1, -2 ) << print( str3 )
<< "\n\n"; // newline after last block, plus extra blank line at bottom
}
This produces the output:
███████ ███████ ███████
███1███ ███2███ ███3███
███████ ███████ ███████
The addition of spacing is, of course, entirely optional and only added for demonstrative purposes.
Advantages: UTF-8 and Pretty colors!
The advantage to this method is that you do not have to store or otherwise take any special care for strings containing multi-byte characters (UTF-8, as yours does) or any additional information like terminal color sequences.
That is, you could color each of your blocks differently by adding a color sequence to each strN variable! (The caveat is that you must repeat a color sequence after every newline. This is a known problem with various terminals...)
// red, white, and blue
std::string str1 = "\033[31m███████\n\033[31m███1███\n\033[31m███████";
std::string str2 = "\033[37m███████\n\033[37m███2███\n\033[37m███████";
std::string str3 = "\033[34m███████\n\033[34m███3███\n\033[34m███████";
Relative vs Absolute Caret Positioning
The other caveat to this particular example is that you must be aware of where the text caret (“cursor”) ends-up after each output. You could also use terminal escape sequences to absolutely position the caret before every output.
std::string gotoxy( int x, int y )
{
std::ostringstream os;
os << "\033[" << y << ";" << x << "H";
return os.str();
}
Then you wouldn’t have to care where the caret ends up. Just specify an absolute position before printing. Just don’t let the text scroll!
Windows OS Considerations
Finally, if you are on Windows and using the old Windows Console, you must initialize the terminal for ANSI terminal sequences and for UTF-8 output:
#ifdef _WIN32
#include <windows.h>
void init_terminal()
{
DWORD mode;
HANDLE hStdOut = GetStdHandle( STD_OUTPUT_HANDLE );
GetConsoleMode( hStdOut, &mode );
SetConsoleMode( hStdOut, mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING );
SetConsoleOutputCP( 65001 );
}
#else
void init_terminal() { }
#endif
int main()
{
init_terminal();
...
This does no harm to the new Windows Terminal. I recommend you do it either way just because you do not know which of the two your user will use to run your program, alas.
I alredy parsed file and split content to enum or enum classes.
std::string sourceString = readFromFile(typesHDestination);
boost::smatch xResults;
std::string::const_iterator Start = sourceString.cbegin();
std::string::const_iterator End = sourceString.cend();
while (boost::regex_search(Start, End, xResults, boost::regex("(?<data_type>enum|enum\\s+class)\\s+(?<enum_name>\\w+)\\s*\{(?<content>[^\}]+?)\\s*\}\\s*")))
{
std::cout << xResults["data_type"]
<< " " << xResults["enum_name"] << "\n{\n";
std::string::const_iterator ContentStart = xResults["content"].begin();
std::string::const_iterator ContentEnd = xResults["content"].end();
boost::smatch xResultsInner;
while (boost::regex_search(ContentStart, ContentEnd, xResultsInner, boost::regex("(?<name>\\w+)(?:(?:\\s*=\\s*(?<value>[^\,\\s]+)(?:(?:,)|(?:\\s*)))|(?:(?:\\s*)|(?:,)))")))
{
std::cout << xResultsInner["name"] << ": " << xResultsInner["value"] << std::endl;
ContentStart = xResultsInner[0].second;
}
Start = xResults[0].second;
std::cout << "}\n";
}
Its ok if enums are without comments.
I tried to add named group <comment> to save comments in enums, but failed every time. (\/{2}\s*.+) - sample for comments with double slashes.
I tested using this online regex and with boost::regex.
The first step - from *.cpp file to <data_type> <enum_name> <content>
regex:
(?'data_type'enum|enum\s+class)\s+(?'enum_name'\w+)\s*{\s*(?'content'[^}]+?)\s*}\s*
From <content> to <name> <value> <comment>
regex:
(?'name'\w+)(?:(?:\s*=\s*(?'value'[^\,\s/]+)(?:(?:,)|(?:\s*)))|(?:(?:\s*)|(?:,)))
The last one contains error. Is there any way to fix it and add feature to store coments in group?
As some comments said, may it is not a good idea to parse a source file with Regular Expression except with some simple cases
for example this source file, from: http://en.cppreference.com/w/cpp/language/enum
#include <iostream>
// enum that takes 16 bits
enum smallenum: int16_t
{
a,
b,
c
};
// color may be red (value 0), yellow (value 1), green (value 20), or blue (value 21)
enum color
{
red,
yellow,
green = 20,
blue
};
// altitude may be altitude::high or altitude::low
enum class altitude: char
{
high='h',
low='l', // C++11 allows the extra comma
};
// the constant d is 0, the constant e is 1, the constant f is 3
enum
{
d,
e,
f = e + 2
};
//enumeration types (both scoped and unscoped) can have overloaded operators
std::ostream& operator<<(std::ostream& os, color c)
{
switch(c)
{
case red : os << "red"; break;
case yellow: os << "yellow"; break;
case green : os << "green"; break;
case blue : os << "blue"; break;
default : os.setstate(std::ios_base::failbit);
}
return os;
}
std::ostream& operator<<(std::ostream& os, altitude al)
{
return os << static_cast<char>(al);
}
int main()
{
color col = red;
altitude a;
a = altitude::low;
std::cout << "col = " << col << '\n'
<< "a = " << a << '\n'
<< "f = " << f << '\n';
}
the key pattern here is: starting with enum and end with ; and you cannot predict any text between enum and ; there will be so many possibilities! and for that you can use .*? lazy star
Thus if I want to extract all enums I use:
NOTE: it is not the efficient way
boost::regex rx( "^\\s*(enum.*?;)" );
boost::match_results< std::string::const_iterator > mr; // or boost::smatch
std::ifstream ifs( "file.cpp" );
const uintmax_t file_size = ifs.seekg( 0, std::ios_base::end ).tellg();
ifs.seekg( 0, std::ios_base::beg ); // rewind
std::string whole_file( file_size, ' ' );
ifs.read( &*whole_file.begin(), file_size );
ifs.close();
while( boost::regex_search( whole_file, mr, rx ) ){
std::cout << mr.str( 1 ) << '\n';
whole_file = mr.suffix().str();
}
which the output will be:
enum smallenum: int16_t
{
a,
b,
c
};
enum color
{
red,
yellow,
green = 20,
blue
};
enum class altitude: char
{
high='h',
low='l', // C++11 allows the extra comma
};
enum
{
d,
e,
f = e + 2
};
And Of course for such simple thing I prefer to use:
perl -lne '$/=unlef;print $1 while/^\s*(enum.*?;)/smg' file.cpp
that has the same output.
And may this pattern helps you if you want to match each section separately
^\s*(enum[^{]*)\s*({)\s*([^}]+)\s*(};)
But again this is not a good idea except for some simple source files. Since C++ Source Code has free style and not all code writers follow the standard rules. For example with the pattern above, I assumed that (};) the } comes with ; and if someone separates them ( which is still a valid code ) the pattern will be failed to match.
I argree with the fact that using regex to parse complicated data is not the best solution. I'v made an omission of the few major conditions. First of all, i parsed some kind of generated source code containing emuns and enum classes. So there were no suprises in code, and code was regular. So i parsing regular code with regex.
The Answer:
(the first step is the same, the second was fixed)
How to parse enums/emun classes with regex:
The first step - from *.cpp file to <data_type> <enum_name> <content> regex:
(?'data_type'enum|enum\s+class)\s+(?'enum_name'\w+)\s*{\s*(?'content'[^}]+?)\s*}\s*
From <content> to <name> <value> <comment> regex:
^\s*(?'name'\w+)(?:(?:\s*=\s*(?'value'[^,\n/]+))|(?:[^,\s/]))(?:(?:\s$)|(?:\s*,\s*$)|(?:[^/]/{2}\s(?'comment'.*$)))
All test were ok and here is marked text by colors.
I have a console application which I want to print the progress with. However, to make this as nice as possible, I would like to print the percentage updates with a carriage return in order to keep the percentage updating instead of adding new lines with new progress status.
Printing with the carriage return works great, until I get a string that outranges the width of my console window. Obviously, the carriage return is not going to return to the start of the string which is longer than the console window.
Is there a possibility to catch this occurrence and somehow start at the beginning of the string again?
Visualized problem:
string = "This is a test string which is longer than the console";
|<- Console width ->|
|This is a test string which is|
->| longer than the console |
The carriage return makes the string being printed starting from the -> as visualized above
The problem is that console windows differ. On the Windows platform you can adjust the width and height of the console.
You may be able to find some API that will return the height and width of the console window; but there is no requirement for a platform to support that.
There are libraries that can assist with cursor positioning. Search Software Recommendations (at StackExchange) to see what they recommend or search the internet for "c++ cursor position library".
On Linux, are you looking for something like this?
#include <sys/ioctl.h>
#include <unistd.h>
#include <stdio.h>
int main()
{
struct winsize size;
ioctl(STDOUT_FILENO, TIOCGWINSZ, &size);
printf ("%d\n", size.ws_row);
printf ("%d\n", size.ws_col);
}
until I get a string that outranges the width of my console window.
It is possible to create a small util function, in c++, to fetch the current screen dimensions as reported by ncurses.
If you run it prior to each output, you will have the dimension you need to predict 'wraparound' based on string size, and take your desired actions. The use of stringstream can be very useful.
#include <iostream>
#include <iomanip>
#include <vector>
// I prefer to not include ncurses here, see below
// determine current console dimensions
class ConsoleDimensions
{
public:
ConsoleDimensions() = default;
~ConsoleDimensions() = default;
//
std::string operator()();
};
class T504_t // or any class name you want
{
public:
T504_t() = default;
~T504_t() = default;
int exec()
{
std::cout << "\n\n" << ConsoleDimensions()() << std::endl;
// invokes operator()--^^
return(0);
}
}; // class T504_t
int main(int argc, char* argv[])
{
std::cout << "\nargc: " << argc << std::endl;
for (int i = 0; i < argc; i += 1) std::cout << argv[i] << " ";
std::cout << std::endl;
int retVal = -1;
{
T504_t t504;
retVal = t504.exec();
}
std::cout << "\n\n <<< If your C++ 'Hello World' has no class ... "
<<" why bother? >>> \n\n"
<< std::endl;
return(retVal);
}
// separate this implementation file (.cc)
// to prevent the curses macros from polluting your non-curses code
#include "cursesw.h"
std::string ConsoleDimensions::operator()()
{
(void)initscr(); // start curses mode
cbreak();
noecho();
// erase()
// refresh()
raw();
// nonl();
// intrFlush(stdscr, FALSE)
keypad(stdscr, true);
// curses uses int (will there ever be a negative height or width?)
int curses_reported_height = 0;
int curses_reported_width = 0;
getmaxyx(stdscr, curses_reported_height, curses_reported_width);
std::stringstream ss;
ss << " max y: " << curses_reported_height
<< " max x: " << curses_reported_width;
endwin();
return(ss.str());
}
The output when running this on a full-screen standard gnome-terminal with default font:
max y: 70 max x: 266
You possibly just want the numbers, not the text. It is easy to change
std::string ConsoleDimensions::operator()();
I would consider,
void ConsoleDimensions::operator()(int& maxY, int& maxX);
with appropriate implementation changes.
Update 2017-07-22
Performance estimates using std::chrono::high_resolution_clock and form "void ConsoleDimensions::operator()(int& maxY, int^ maxX);"
171.2830000 k ConsoleDimension()(int&, int&) events in 4,000,006 us
42.82068577 k ConsoleDimension()(int&, int&) events per second
23.35319909 µ sec per ConsoleDimension()(int&, int&) event
dimensions [50,100]
Your results will vary.
As in c we can use various format specifiers like
%nd where n is a number, to print the number with a total of atleast n space covered
%0nd same as above, except pre-padding with 0's " %05d ",3 => 00003
%.nf to set precision of n after decimal
etc ....
So is there any way to use these with std::cout ?
I got some negative feedback in a recent course (c++ for c programmers) in coursera, for using printf instead of cout because i wanted to some formatting :(
For %nd %0nd, C++ equivalents are std::setw() and std::setfill().
#include <iostream> // std::cout, std::endl
#include <iomanip> // std::setfill, std::setw
int main () {
std::cout << std::setfill ('x') << std::setw (10);
std::cout << 77 << std::endl;
return 0;
}
Output: xxxxxxxx77
%.nf can be replaced by std::setprecision and std::fixed,
#include <iostream> // std::cout, std::fixed, std::scientific
int main () {
double a = 3.1415926534;
double b = 2006.0;
double c = 1.0e-10;
std::cout.precision(5);
std::cout << "fixed:\n" << std::fixed;
std::cout << a << '\n' << b << '\n' << c << '\n';
return 0;
}
Output:
fixed:
3.14159
2006.00000
0.00000
C++ streams don't use format-specifiers like C's printf()-type functions; they use manipulators.
For example:
#include <iostream>
#include <iomanip>
int main()
{
std::cout << std::fixed << std::setprecision(6) << 42.0 << std::endl;
}
Output:
42.000000
See it run!
The usual solution in C++ is to defined manipulators which state
what your trying to format, rather than to hack physical values
directly at the point of output. (One possible exception is the
width, where std::setw may be useful directly.) Thus, for
example, when actually outputting something, you won't specify
zero padding, or fixed, with 2 decimals, but something like:
std::cout << temperature(2) << theTemporature;
where temperature would be something like:
class temperature
{
int myMinWidth;
public:
temperature( int minWidth )
: myMinWidth( minWidth )
{
}
friend std::ostream& operator<<( std::ostream& dest, temperature const& manip )
{
dest.setf( std::ios_base::fixed, std::ios_base::floatfield );
dest.precision( 2 );
dest.width( myMinWidth );
return dest;
}
};
For the list of format modifications available, see the
specification of std::ios_base, and the fields of
std::ios_base::fmtflags.
If you're doing a lot of output, you might want to modify this
to restore the original format flags at the end of the full
expression. (All of the format information except the width is
sticky, so forcing fixed format here leaves you with fixed
format for the rest of the program, which isn't necessarily what
you want.) I use the following as base class for all of my
manipulators:
class StateSavingManip
{
public:
void operator()( std::ios& stream ) const;
protected:
StateSavingManip() : myStream( nullptr ) {}
~StateSavingManip();
private:
virtual void setState( std::ios& stream ) const = 0;
private:
mutable std::ios* myStream;
mutable std::ios::fmtflags mySavedFlags;
mutable int mySavedPrec;
mutable char mySavedFill;
};
implementation:
namespace {
int getXAlloc() ;
int ourXAlloc = getXAlloc() + 1 ;
int
getXAlloc()
{
if ( ourXAlloc == 0 ) {
ourXAlloc = std::ios::xalloc() + 1 ;
assert( ourXAlloc != 0 ) ;
}
return ourXAlloc - 1 ;
}
}
StateSavingManip::~StateSavingManip()
{
if ( myStream != nullptr ) {
myStream->flags( mySavedFlags ) ;
myStream->precision( mySavedPrec ) ;
myStream->fill( mySavedFill ) ;
myStream->pword( getXAlloc() ) = NULL ;
}
}
void
StateSavingManip::operator()(
std::ios& stream ) const
{
void*& backptr = stream.pword( getXAlloc() ) ;
if ( backptr == nullptr ) {
backptr = const_cast< StateSavingManip* >( this ) ;
myStream = &stream ;
mySavedFlags = stream.flags() ;
mySavedPrec = stream.precision() ;
mySavedFill = stream.fill() ;
}
setState( stream ) ;
}
Note the use of the pword field to ensure that only the first
temporary manipulator restores the format; the destructors will
be called in the reverse order of construction, but the order of
construction will typically not be specified if you have more
than one such manipulator in an expression.
Finally: not everything is possible using this technique: if you
want to systematically append a degree sign to the temperature,
there's no way of doing so. In this case, you need to define
a class Temperature, and overload the << operator for it; this
allows everything imaginable (much more than you could ever
achieve with printf style formatting).
C++ stream manipulators (iomanip) were specifically designed to support all of the standard c format specifiers operations, just with an entirely different interface. E.g. setfill and setw for the width and fill part of %02d.
Of course if you really need format strings (e.g. because it makes i18n easier for you), then you should have a look at boost::format, and if you have C++11 then you can easily write small variadic template wrapper around it, to make the format call look more like printf.
Whatever you do, please try to not use printf. It is not typesafe, and not extendible for output operations on user defined types.
There are stream manipulators, if you need them. But I think you want to know this thing: cout is smarter than printf().
Say you have:
int x = 34;
cout<<x;
Now the compiler will call:
ostream& operator<<(ostream& stream, int arg);
for you. And this function will print the output in console( since in your case stream is cout). The standard library supplies overloads for this << operator for all fundamental datatype available.
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.