// takeInUtilities.h // // 2013-08-18 //
#ifndef TAKEINUTILITIES_H
#define TAKEINUTILITIES_H
#include <iostream>
#include <string>
#include <cctype> // re. tolower, toupper ...
#include <limits> // re. numeric_limits
namespace TakeInUtilities
{
// use this for your (one on a line) numeric input (only) ... //
template < typename T >
T takeInNum
(
const std::string& msg,
const T& min = std::numeric_limits< T >::min(),
const T& max = std::numeric_limits< T >::max(),
const std::string& errMsg = "\nInvalid numeric input!\n"
)
{
T val;
while( true )
{
std::cout << msg << std::flush;
if( std::cin >> val && std::cin.get() == '\n'
&& val >= min && val <= max )
break;
else
{
std::cout << errMsg;
std::cin.clear();
std::cin.sync();
}
}
return val;
}
// defaults to 'noEmpty' ... i.e. don;t accept an empty string, but
// allows an empty string as valid input if 'noEmpty' set to false
std::string takeInStr( const std::string& msg,
bool noEmpty = true,
const std::string& errMsg =
"\nA 'blank line' is "
"NOT valid input here ...\n" )
{
std::string val;
for( ; ; )
{
std::cout << msg << std::flush;
getline( std::cin, val );
if( noEmpty )
{
if( val.size() )
break;
else // loop again ... //
std::cout << errMsg;
}
else
break;
}
return val;
}
std::string& toCapsOnAllFirstLetters( std::string& str )
{
int prev_was_space = 1;
int len = str.size();
for( int i = 0; i < len; ++ i )
{
if( prev_was_space )
str[i] = std::toupper( str[i] );
prev_was_space = std::isspace( str[i] );
}
return str;
}
std::string& toAllCaps( std::string& str )
{
int len = str.size();
for( int i = 0; i < len; ++ i )
{
if( std::isalpha( str[i] ) )
str[i] = std::toupper ( str[i] );
}
return str;
}
// default allows an empty 'takeIn' ...
char takeInChr( const std::string& msg, bool noEmpty = false )
{
std::string reply = takeInStr( msg, noEmpty );
if( reply.size() == 1 )
return reply[0];
// else ...
return 0;
}
// must explicity enter 'n' (or 'N') to have NO more ...
// interprets empty line input as ... 'yes -> more'
bool more() // defaults to more ... yes ... more ... //
{
if( tolower( takeInChr( "More (y/n) ? " )) == 'n' )
return false;
// else ...
return true;
}
}
#endif
// test_takeInUtilities.h.cpp // // 2013-08-18 //
#include <iomanip>
#include "takeInUtilities.h"
const char* HEADER = "\n\t\tYour 'Beginning Student' Billing Software\n";
const int MAX_ARY_SIZE = 2; // keep small while testing/debugging ... //
// Note the 5 data members in this data 'record' / data 'struct'
struct Product
{
std::string itemName;
int numItems;
double unitPrice; // in local units per item ... //
// Next two data members are re. customer "internal stat's" ...
char fm; // track if item was purchased for female or male
// track any customer comments about this product (max 160 char's)
std::string comments;
// Note: it C++ a struct (or a class) can have methods
// (functions) that are used to handle data
double lineTotal() const { return numItems * unitPrice; }
} ; // <-- note semi-colon to tell compiler struct is 'done' ... //
// Note: passed by ref... (so calling scope 'prod' updated) ... //
void takeIn( Product& prod )
{
prod.itemName =
TakeInUtilities::takeInStr( "Item name : " );
TakeInUtilities::toAllCaps( prod.itemName );
prod.numItems =
TakeInUtilities::takeInNum< int >( "Quantity : ", 1, 10,
"\nValid input is a number >= 1 & <= 10 \n" );
prod.unitPrice =
TakeInUtilities::takeInNum< double >( "Unit price : ", 0.0,
1000.00, "\nValid input is a number >= 0.0 & <= 1000.00\n" );
for( ; ; ) // an example of a C/C++ forever loop ... //
{
prod.fm = TakeInUtilities::takeInChr
( "Purchase for female/male : " );
if( prod.fm == 'm' || prod.fm == 'f' || prod.fm == 0 ) break;
// else ...
std::cout << "\nOnly f or m or 'blank' valid input here ...\n";
}
for( ; ; )
{
prod.comments = TakeInUtilities::takeInStr
( "Any comments about this product (max char's = 160) : " );
if( prod.comments.size() <= 160 ) break;
// else ...
std::cout << "\nSorry " << prod.comments.size()
<< " char's won't fit in here ...\n";
}
}
void showBill( const Product cart[], int size )
{
using std::setw;
using std::cout;
cout << "\nYour cart ...\n"
<< setw( 20 ) << "Item"
<< setw( 15 ) << "Quanity"
<< setw( 15 ) << "Unit Price"
<< setw( 15 ) << "Line Total"
<< '\n';
double sumTotal = 0.0;
// show 2 decimal places in money
cout << std::fixed << std::setprecision( 2 );
// NOTE! In C/C++ ... arrays start with index 0 ...
for( int i = 0; i < size; ++ i )
{
cout << ' ' << setw( 19 ) << cart[i].itemName
<< ' ' << setw( 14 ) << cart[i].numItems
<< ' ' << setw( 14 ) << cart[i].unitPrice
<< ' ' << setw( 14 ) << cart[i].lineTotal()
<< '\n';
sumTotal += cart[i].lineTotal();
}
cout << "\n\nTOTAL: " << sumTotal << " local units of money."
<< "\n\nTHANK YOU FOR YOUR PURCHASE TODAY."
<< "\n\nPLEASE VISIT AGAIN SOON.\n";
}
void showStats( const Product cart[], int size )
{
using std::setw;
using std::cout;
cout << "\nYour stat's ...\n"
<< setw( 20 ) << "Item"
<< setw( 15 ) << "Quantity"
<< setw( 15 ) << "For use by"
<< " Comments"
<< '\n';
// NOTE! In C/C++ ... arrays start with index 0 ...
for( int i = 0; i < size; ++ i )
{
cout << ' ' << setw( 19 ) << cart[i].itemName
<< ' ' << setw( 14 ) << cart[i].numItems
<< ' ' << setw( 14 ) << cart[i].fm
<< " " << cart[i].comments
<< '\n';
}
}
int main()
{
Product cart[MAX_ARY_SIZE]; // get room to hold this many products
using std::cout;
cout << HEADER
<< "\nBelow you will be asked to enter ...\n"
<< "\nITEM NAME,\nQUANTITY,\nUNIT PRICE,\n\nfor each item.\n";
int no = 0; // inital num products in cart ... //
do
{
cout << "\nFor item " << (no+1) << ", please enter ... \n";
takeIn( cart[no] );
cout << '\n';
++no;
if( no == MAX_ARY_SIZE )
{
cout << "\nYou have reached the max cart size "
<< "allowed here of " << no << " order lines.\n"
<< "Proceeding to 'Check-Out' right now ...\n";
break;
}
}
while( TakeInUtilities::more() );
showBill( cart, no );
showStats( cart, no );
TakeInUtilities::takeInStr // allow an empty string as input ... //
( "\nPress 'Enter' to continue/exit ... ", false );
}
// test_takeIns.h.cpp // // 2013-08-18 //
#include "takeIns.h"
// functor def'n needed by following 'takeInString' ... //
// also ... returns string passed in with first letters in Caps ... //
struct NoBlankLine
{
// ctor...
NoBlankLine( bool noEmpty ) : yes( noEmpty ) {}
// def'n of overloaded operator () for NoBlankLine
bool operator() ( const std::string& s ) const
{
return yes ? s.size() : true;
}
private:
bool yes;
} ;
// will not accept an empty string if noEmpty has default value of true
std::string takeInString( const std::string& msg,
bool noEmpty = true,
const std::string& errMsg =
"\nBlank line not valid here!\n" )
{
// firstly, input string using TakeIns::takeIn (with condition):
std::string result = TakeIns::takeIn < std::string, NoBlankLine >
(
msg, NoBlankLine( noEmpty ), errMsg
);
return result;
}
// Now ... 3 more functor def'ns needed in main ... //
struct GreaterThanIntZero
{
bool operator() ( int i ) const { return i > 0; }
} ;
struct NoNegs
{
bool operator() ( double i ) const { return i >= 0.0; }
} ;
struct MaleFemale
{
bool operator() ( char i ) const { return i == 'm' || i == 'f'; }
} ;
int main()
{
do
{
std::string name = takeInString( "Enter your name : " );
std::cout << "\nYour entered : " << name;
TakeIns::toCapsOnAllFirstLetters( name );
std::cout << "\nWith Caps on first letters : " << name
<< "\n\n";
int id = TakeIns::takeIn < int, GreaterThanIntZero >
(
"Enter your id : ",
GreaterThanIntZero(),
"\nValid here are int size numbers > 0\n"
);
std::cout << "\nYou entered " << id << "\n\n";
double pay = TakeIns::takeIn < double, NoNegs >
(
"Enter your payment : ",
NoNegs(),
"\nValid here are decimal numbers >= 0.0\n"
);
std::cout << "\nYou entered: " << pay << "\n\n";
char sex = TakeIns::takeIn < char, MaleFemale >
(
"Female/Male (f/m) : ",
MaleFemale(),
"\nValid entries are only f or m\n"
);
std::cout << "\nYou entered " << sex << "\n\n";
std::string comments = takeInString
(
"Enter any comments : ",
false /* allow a blank line ... as valid entry ... */
);
std::cout << "\nYou entered: \"" << comments << "\"\n\n";
}
while( TakeIns::more() );
}
// takeIns.h // // 2013-08-19 //
// Acknowledgement:
// The 'design here' was adapted from one suggested by Mike
// in response to my post at DaniWeb earlier this month ...
// Thank you Mike : ) ... //
#ifndef TAKEINS_H
#define TAKEINS_H
#include <iostream>
#include <string>
#include <cctype> // re. tolower, toupper ...
// The 'prime focus here' is JUST taking in (user entered) ...
// primitive types ... numbers, C++ strings and char ...
// so that a C++ student has a READY template to take in validated
// primitive data ... (prompting for one item of data at a time) ...
// without the 'progam crashing' on 'bad data' entered by a user at
// the keyboard ...
// i.e. this is NOT for getting data from a file ... //
namespace TakeIns
{
template < typename T >
bool get_val( T& val )
{
std::cin >> val;
return std::cin && ( std::cin.get() == '\n' );
// making sure NO extra non-numeric char's after number ... //
}
inline
bool get_val( std::string& s )
{
getline( std::cin, s );
return std::cin;
}
inline
bool get_val( char& c )
{
std::string s;
getline( std::cin, s );
if( s.size() )
c = s[0];
else c = 0;
return std::cin && s.size() <= 1;
}
// takeIn (in a loop) until valid ...
// with a condition to meet before accepting ... //
template < typename T, typename Predicate >
T takeIn( const std::string& msg, const Predicate& pred,
const std::string& errMsg = "\nInvalid input!\n" )
{
T result = T();
while( true )
{
std::cout << msg << std::flush;
if( get_val( result ) && pred( result ) )
{
std::cin.sync();
break;
}
else
{
std::cout << errMsg;
std::cin.clear();
std::cin.sync();
}
}
return result;
}
// takeIn (in a loop) until valid type before accepting ... //
template < typename T >
T takeIn( const std::string& msg,
const std::string& errMsg = "\nInvalid input!\n" )
{
T result = T();
while( true )
{
std::cout << msg << std::flush;
if( get_val( result ) )
{
std::cin.sync();
break;
}
else
{
std::cout << errMsg;
std::cin.clear();
std::cin.sync();
}
}
return result;
}
// (no loop) just take in (the first) char entered (on a line) ... //
char takeInChar( const std::string& msg )
{
std::cout << msg << std::flush;
char c;
get_val( c );
return c;
}
// defaults to yes ... do more ... //
bool more()
{
return ( tolower( takeInChar( "More (y/n) ? " ) ) != 'n' );
}
std::string& toCapsOnAllFirstLetters( std::string& str )
{
int prev_is_space = 1;
int len = str.size();
for( int i = 0; i < len; ++ i )
{
if( prev_is_space )
str[i] = std::toupper( str[i] );
prev_is_space = std::isspace( str[i] );
}
return str;
}
std::string& toAllCaps( std::string& str )
{
int len = str.size();
for( int i = 0; i < len; ++ i )
str[i] = std::toupper ( str[i] );
return str;
}
}
#endif
// takeInStuff_C++11.cpp // // 2013-08-19 //
// uses C++11 lambda functions like: []( int i ) { return i > 0; }
// uses C++11 (for each) function like: for( char& c : inResultCstr )
#include <iomanip>
#include "takeIns.h"
#include "commasAdded.h"
#include "trim_split_cpp.h"
// Using a C++11 lambda function here ...
// Will not accept an empty string if noEmpty is 'true' (default)
// to get special def'n used here to 'takeInString' ... //
std::string takeInString( const std::string& msg, bool noEmpty = true )
{
// Using 'TakeIns::takeIn' (with condition) to get input ... //
std::string result = TakeIns::takeIn < std::string >
(
msg, // prompt msg passed in ... //
[noEmpty]( const std::string& s ) // lambda def'n begins ...
{
return ( noEmpty ? s.size() : true ); // if no blank lines
// allowed, make sure size!=0, otherwise, blank line ok //
}, // end of lambda function def'n ... //
"\nBlank line not valid here!\n" // errMsg passed in ... //
);
return result;
}
int main()
{
do
{
std::string name = takeInString( "Enter your name : " );
std::cout << "\nYou entered : \"" << name << '"';
std::string t_name = copy_trim::trim( name );
TakeIns::toCapsOnAllFirstLetters( t_name );
std::cout << "\nTrimmed and Caps : \"" << t_name << "\"\n\n";
int id = TakeIns::takeIn < int >
(
"Enter your id : ",
[]( int i ) { return i > 0; },
"\nValid here are 'int' size numbers > 0\n"
);
std::cout << "\nYou entered : "
<< commasAddedStr( id ) << "\n\n";
double pay = TakeIns::takeIn < double >
(
"Enter your payment : ",
[]( double i ) { return i >= 0; },
"\nValid here are decimal numbers >= 0.0\n"
);
std::cout << std::setprecision(2) << std::fixed;
std::cout << "\nYou entered : $" << pay << "\n\n";
char sex = TakeIns::takeIn < char >
(
"Male/Female (f/m) : ",
[]( char i ) { return i == 'm' || i == 'f'; },
"\nValid entries are only f or m\n"
);
std::cout << "\nYou entered : " << sex << "\n\n";
// Using 'TakeIns::takeIn' (with NO condition) for input ... //
std::string comments = TakeIns::takeIn < std::string >
(
"Enter any comments : "
);
void_trim::trim( comments );
std::cout << "\nTrimmed, was ... : \"" << comments << "\"\n";
std::list< std::string > myLst;
split( myLst, comments );
std::cout << "There were " << myLst.size()
<< " words in the comments\n";
std::cout << std::endl;
}
while( TakeIns::more() );
}
// trim_split_cpp.h // this version 2013-08-19 //
// http://developers-heaven.net/forum/index.php/topic,46.0.html
#ifndef TRIM_SPLIT_CPP_H
#define TRIM_SPLIT_CPP_H
#include <string>
#include <list>
// returns a new list of strings ... //
std::list < std::string > split( const std::string& s,
const std::string delimits = " \t" )
{
std::list < std::string > tmp;
size_t p1, p2 = 0;
for( ; ; ) // loop forever ... until break
{
p1 = s.find_first_not_of( delimits, p2 ); // Note: p2 is 0 on first loop
if( std::string::npos == p1 ) break; // i.e. if empty or all delimits
p2 = s.find_first_of( delimits, p1+1 );
if( std::string::npos != p2 ) // i.e. if still more ... p2 is not past end
tmp.push_back( s.substr( p1, p2-p1 ) );
else
{
tmp.push_back( s.substr( p1 ) );
break;
}
}
return tmp;
}
// adds to list of strings passed in by ref... //
void split( std::list < std::string>& lst, const std::string& s,
const std::string delimits = " \t" )
{
size_t p1, p2 = 0;
for( ; ; ) // loop forever ... until break
{
p1 = s.find_first_not_of( delimits, p2 ); // Note: p2 is 0 on first loop
if( std::string::npos == p1 ) break; // i.e. if empty or all delimits
p2 = s.find_first_of( delimits, p1+1 );
if( std::string::npos != p2 ) // i.e. if still more ... p2 is not past end
lst.push_back( s.substr( p1, p2-p1 ) );
else
{
lst.push_back( s.substr( p1 ) );
break;
}
}
}
namespace copy_trim
{
// trim leading and trailing whitespaces from returned copy of 's'...
std::string trim( const std::string& s, const std::string t = " \t" )
{
//std::cout << "\ncopy version ...\n";
size_t p1 = s.find_first_not_of( t );
if( std::string::npos != p1 ) // ok, not all ws or empty so can safely
{
size_t p2 = s.find_last_not_of( t ); // get index of 'last char' ...
return s.substr( p1, p2+1-p1 );
}
// else ... all whitespaces or empty ... so return an empty string
return "";
}
// trim leading whitespaces only ...
std::string ltrim( const std::string& s, const std::string t = " \t" )
{
size_t p1 = s.find_first_not_of( t );
if( std::string::npos != p1 )
return s.substr( p1 );
// else ...
return "";
}
// trim trailing whitespaces only ...
std::string rtrim( const std::string& s, const std::string t = " \t" )
{
size_t p2 = s.find_last_not_of( t );
if( std::string::npos != p2 )
return s.substr( 0, p2+1 );
// else ...
return "";
}
} //end copy_trim namespace
namespace void_trim
{
// trim leading and trailing whitespaces from 's' ... and return by 'ref.'
void trim( std::string& s, const std::string t = " \t" ) // default whitespace: "\t "
{
//std::cout << "\nvoid version ...\n";
size_t p1 = s.find_first_not_of( t ); // get index of 'first char' ...
if( std::string::npos != p1 ) // ok ... not all ws or empty ... so can safely
{
s.erase( 0, p1);
size_t p2 = s.find_last_not_of( t ); // get index of 'last char' ...
s.erase( p2+1 );
}
else // ... all whitespaces or empty
s.clear();
}
// trim trailing whitespaces only ...
void rtrim( std::string& s, const std::string t = " \t" )
{
size_t p2 = s.find_last_not_of( t );
if( std::string::npos != p2 )
s.erase( p2+1 );
else
s.clear();
}
// trim leading whitespaces only ...
void ltrim( std::string& s, const std::string t = " \t" )
{
size_t p1 = s.find_first_not_of( t );
if( std::string::npos != p1 )
s.erase( 0, p1 );
else
s.clear();
}
} //end void_trim namespace
#endif
// commasAdded.h // // 2013-08-19 //
#ifndef COMMAS_ADDED_H
#define COMMAS_ADDED_H
#include <sstream>
#include <string>
// use this (only) for NON decimal numbers ...
// for example ... where T is int, long, long long, unsigned, ... //
template < typename T >
std::string commasAddedStr( T val, std::string showSign = "" )
{
std::stringstream ss;
ss << val;
std::string tmp;
ss >> tmp;
if( tmp[0] == '-' )
{
showSign = "-";
tmp.erase( 0, 1 ); // erase neg sign from tmp string
}
int len = tmp.size();
int len2 = len + (len-1)/3;
// construct right sized container string filled with commas ... //
std::string tmp2( len2, ',' );
int comma = 0;
while( len2 )
{
--len, --len2, ++comma;
if( comma == 4 )
{
comma = 1;
--len2; // skip over 'comma' for this copy ... //
}
tmp2[len2] = tmp[len];
}
return showSign+tmp2;
}
#endif
// classDateTime.h // 2013-08-18 //
#ifndef CLASSDATETIME_H
#define CLASSDATETIME_H
/*
For BEGINNING COMPUTER PROGRAMMING using HLA, Python, C/C++, goto ...
http://developers-heaven.net/forum/index.php/topic,46.0.html
*/
#include <iostream>
#include <iomanip> // setw, setfill
#include <sstream>
#include <string>
#include <ctime>
#include <cctype> // toupper
//using namespace std;
class DateTime
{
private:
int year;
int month; // 0..11 // get_month() const {return month + 1;}
int day; // 1..31
int weekday; // 0..6 // returns weekday + 1
int hour; // 0..23
int minute; // 0..59
int second; // 0..59
public:
DateTime() // default constructor to fill up private time data 'right now'
{
time_t now = time( 0 );
std::istringstream iss( ctime( &now ) ); // "Fri Nov 27 16:22:24 2009"
std::string weekdayStr, monthStr;
char c; // dummy char to hold ':' char between hour:minute:second //
iss >> weekdayStr >> monthStr >> day
>> hour >> c >> minute >> c >> second // using char 'c' to skip ':'
>> year;
weekday = find_weekday( weekdayStr );
month = find_month( monthStr );
}
std::string get_date() const
{
std::ostringstream oss;
oss << year
<< "-" << std::setfill('0') << std::setw(2) << (month+1)
<< "-" << std::setw(2) << day << std::setfill(' ');
return oss.str();
}
std::string get_time() const
{
std::ostringstream oss;
oss << std::setfill('0') << std::setw(2) << hour
<< ":" << std::setw(2) << minute
<< ":" << std::setw(2) << second << std::setfill(' ');
return oss.str();
}
std::string get_date_time() const { return get_date() + " " + get_time(); }
std::string get_weekdayname() const { return daysTable[ weekday ]; }
std::string get_weekdaynameL() const { return daysTable[ weekday+14 ]; }
std::string get_weekdaynumber() const { return daysTable[ weekday+7 ]; } //1st,2nd...7th
std::string get_monthname() const { return monthsTable[ month ]; }
std::string get_monthnameL() const { return monthsTable[ month+24 ]; }
std::string get_monthnumber01() const { return monthsTable[ month+12 ]; }
std::string get_monthnumber() const { return monthsTable[ month+36 ]; } //1st,2nd...12th
std::string get_monthdaynumber() const{ return dayOfMonthTable[ day-1 ]; }//1st,2nd...31st
int get_year() const { return year; }
int get_month() const { return month + 1; }
int get_day() const { return day; }
int get_weekday() const { return weekday + 1; }
int get_hour() const { return hour; }
int get_minute() const { return minute; }
int get_second() const { return second; }
private:
static const std::string monthsTable[];
static const std::string daysTable[];
static const std::string dayOfMonthTable[];
static int find_weekday( std::string wdStr )
{
for( int n = 0; n < 7; ++n )
if( daysTable[n] == wdStr ) return n; // 0..6
// else if error ... handle ... but for now ... out of bounds error
return 7;
}
static int find_month( std::string mStr )
{
for( int n = 0; n < 12; ++n )
if( monthsTable[n] == mStr ) return n; // 0..11
// else if error ... handle ... but for now ... out of bounds error
return 12;
}
};
// define your (language) static const arrays here ... (after declaration above)
const std::string DateTime::daysTable[] =
{
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat",
"1st", "2nd", "3rd", "4th", "5th", "6th", "7th",
"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
"Friday", "Saturday"
};
const std::string DateTime::monthsTable[] =
{
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
"01", "02", "03", "04", "05", "06",
"07", "08", "09", "10", "11", "12",
"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December",
"1st", "2nd", "3rd", "4th", "5th", "6th",
"7th", "8th", "9th", "10th", "11th", "12th"
};
const std::string DateTime::dayOfMonthTable[] =
{
"1st", "2nd", "3rd", "4th", "5th", "6th",
"7th", "8th", "9th", "10th", "11th", "12th",
"13th", "14th", "15th", "16th", "17th", "18th",
"19th", "20th", "21st", "22nd", "23rd", "24th",
"25th", "26th", "27th", "28th", "29th", "30th", "31st"
};
#endif
// test_takeInUtilities_cpp.h.cpp // // 2015-05-02 //
#include "takeInUtilities_cpp.h"
int main()
{
do
{
int iVal = takeIn< int > ("Take in an int: " );
std::cout << "You took in " << iVal << '\n';
std::cout << "with commas " << toStrCommasAdded(iVal) << '\n';
double dVal = takeIn< double > ("Take in a double: " );
std::cout << "You took in " << dVal << '\n';
std::cout << "with commas " << toStrCommasAdded(dVal) << '\n';
char cVal = takeIn< char > ("Take in a char: " );
std::cout << "You took in " << cVal << '\n';
std::string sVal = takeIn< std::string > ("Take in a C++ string: " );
std::cout << "You took in " << sVal << '\n';
const char* cStr = takeInCstr( "Take in a C string: " );
std::cout << "You took in " << cStr << '\n';
const char* ccStr = takeInLineCstrMaxLen( "Take in line as Cstr, (max len = 79): ", 79 );
std::cout << "You took in " << ccStr << '\n';
// need a 'mutable' copy 'in memory' so can change/return
// when passed in/returned by ref... below ... //
std::string tmp(ccStr);
std::cout << "You took in (as Title) " << toCapsOnAllFirstLetters(tmp) << '\n';
std::cout << "You took in (all Caps) " << toAllCaps(tmp) << '\n';
sVal = takeInLine( "Take in line: " );
std::cout << "You took in " << sVal << '\n';
std::cout << "You took in (as Title) " << toCapsOnAllFirstLetters(sVal) << '\n';
std::cout << "You took in (all Caps) " << toAllCaps(sVal) << '\n';
}
while( more() );
}
// takeInUtilities_cpp.h // // 2015-05-02 //
#ifndef TAKEINUTILITIES_CPP_H
#define TAKEINUTILITIES_CPP_H
#include <iostream>
#include <sstream>
#include <string>
#include <cstring> // re. strlen, strcpy...
#include <cctype> // re. isspace, tolower, toupper...
//////// 16 prototypes for utilities to ease coding ////////
template< typename T >
T takeIn( const std::string& msg,
const std::string& errMsg = "\nInvalid ... try again please ...\n\n" ) ;
// remember to delete new Cstring when done with it ... //
const char* takeInCstr( const std::string& msg,
const std::string& errMsg = "\nInvalid ... try again please ...\n\n" ) ;
template< typename T >
T takeInMin( const std::string& msg, T min = 0,
const std::string& errMsg = "\nNumbers ONLY please ...\n\n") ;
template< typename T >
T takeInMax( const std::string& msg, T max,
const std::string& errMsg = "\nNumbers ONLY please ...\n\n") ;
template< typename T >
T takeInMinMax( const std::string& msg, T min, T max,
const std::string& errMsg = "\nNumbers ONLY please ...\n\n") ;
// convert number of type T to string ...
template < typename T >
std::string numberToString( T val ) ;
// convert string to number of type T ...
template < typename T >
T stringToNumber( const std::string& str ) ;
// return a (Non-empty?) C++ string //
std::string takeInLine( const std::string& msg, bool okEmpty = false ) ;
// return a (Non-empty?) C string ... with up to maxLen char's //
const char* takeInLineCstrMaxLen( const std::string& msg, int maxLen,
bool okEmpty = false ) ;
char* toCapsOnAllFirstLetters( char* str ) ;
std::string& toCapsOnAllFirstLetters( std::string& str ) ;
char* toAllCaps( char* val ) ;
std::string& toAllCaps( std::string& val ) ;
template < typename T >
std::string toStrCommasAdded( T val ) ;
char takeInChr( const std::string& msg ) ;
bool more( const std::string& text = "" ) ;
////////////////////////////////////////////////////////////
//////// 16 definitions for utilities to ease coding ///////
template< typename T >
T takeIn( const std::string& msg, const std::string& errMsg )
{
T val = T();
while( true )
{
std::cout << msg << std::flush;
if( std::cin >> val && std::cin.get() == '\n' )
break;
else
{
std::cout << errMsg;
std::cin.clear(); // clear error flasgs
std::cin.sync(); // 'flush' cin stream ...
}
}
return val;
}
const char* takeInCstr( const std::string& msg, const std::string& errMsg )
{
std::string val;
while( true )
{
std::cout << msg << std::flush;
if( std::cin >> val && std::cin.get() == '\n' )
break;
else
{
std::cout << errMsg;
std::cin.clear(); // clear error flasgs
std::cin.sync(); // 'flush' cin stream ...
}
}
return val.c_str();
}
template< typename T >
T takeInMin( const std::string& msg, T min,
const std::string& errMsg )
{
T val;
while( true )
{
std::cout << msg << std::flush;
if( std::cin >> val && std::cin.get() == '\n' )
{
if( val >= min )
break;
else
std::cout << "\nMin value accepted here is "
<< min << "\n\n";
}
else
{
std::cout << errMsg;
std::cin.clear();
std::cin.sync();
}
}
return val;
}
template< typename T >
T takeInMax( const std::string& msg, T max,
const std::string& errMsg )
{
T val;
while( true )
{
std::cout << msg << std::flush;
if( std::cin >> val && std::cin.get() == '\n' )
{
if( val <= max )
break;
else
std::cout << "\nMax value accepted here is "
<< max << "\n\n";
}
else
{
std::cout << errMsg;
std::cin.clear();
std::cin.sync();
}
}
return val;
}
template< typename T >
T takeInMinMax( const std::string& msg, T min, T max,
const std::string& errMsg )
{
T val;
while( true )
{
std::cout << msg << std::flush;
if( std::cin >> val && std::cin.get() == '\n' )
{
if( val >= min && val <= max )
break;
else
std::cout << "\nValid range accepted here is "
<< min << ".." << max << "\n\n";
}
else
{
std::cout << errMsg;
std::cin.clear();
std::cin.sync();
}
}
return val;
}
// convert number of type T to string ...
template < typename T >
std::string numberToString( T val )
{
std::ostringstream oss;
oss << val;
return oss.str();
}
// convert string to number of type T ...
template < typename T >
T stringToNumber( const std::string& str )
{
std::istringstream iss( str );
T tmp;
iss >> tmp;
return tmp;
}
// return a (Non-empty) C string ... with up to maxLen char's ...
const char* takeInLineCstrMaxLen( const std::string& msg,
int maxLen, bool okEmpty )
{
std::string val;
while( true )
{
std::cout << msg << std::flush;
getline( std::cin, val );
int len = val.size();
if( len )
{
if( len <= maxLen ) break;
// else
std::cout << "\nMax allowed length is "
<< maxLen << " char's\n";
}
else if( okEmpty ) // case of blank lines accepted as input //
break;
else
std::cout << "\nBlank line input is NOT valid here ...\n\n";
}
return val.c_str();
}
// return a (Non-empty) C++ string ... with up to maxLen char's ...
std::string takeInLine( const std::string& msg, bool okEmpty )
{
std::string val;
while( true )
{
std::cout << msg << std::flush;
getline( std::cin, val );
if( okEmpty )
break;
// else ...
if( val.size() )
break;
// else ...
std::cout << "\nEmpty line input is NOT valid here ...\n\n";
}
return val;
}
char* toCapsOnAllFirstLetters( char* str )
{
// to get CAPS on first char ...
if( str )
{
bool prev_was_ws = true; // start with previous was white space
int len = std::strlen( str );
for( int i = 0; i < len; ++ i )
{
if( prev_was_ws )
str[i] = std::toupper( str[i] );
prev_was_ws = std::isspace( str[i] );
}
}
return str;
}
std::string& toCapsOnAllFirstLetters( std::string& str )
{
// to get CAPS on first char ...
bool prev_was_ws = true; // start with previous was white space
int len = str.size();
for( int i = 0; i < len; ++ i )
{
if( prev_was_ws )
str[i] = std::toupper( str[i] );
prev_was_ws = std::isspace( str[i] );
}
return str;
}
char* toAllCaps( char* val )
{
if( val )
{
size_t len = strlen(val) ;
while( len )
{
--len;
val[len] = toupper( val[len] );
}
}
return val;
}
std::string& toAllCaps( std::string& val )
{
size_t len = val.size();
while( len )
{
--len;
val[len] = toupper( val[len] );
}
return val;
}
template < typename T >
std::string toStrCommasAdded( T val )
{
std::stringstream ss;
ss << val;
std::string tmp, decimal;
ss >> tmp;
char sign = ' '; // use space for pos sign //
if( tmp[0] == '-' )
{
sign = '-';
tmp.erase( 0, 1 ); // erase neg sign from tmp string //
}
size_t pos;
if( (pos = tmp.find('.')) != std::string::npos )
{
decimal = tmp.substr( pos ); // includes leading decimal point //
tmp.erase( pos );
}
int len = tmp.size();
int len2 = len + (len-1)/3;
// construct right size and filled with commas //
std::string tmp2( len2, ',' );
int comma = 0;
while( len2 )
{
--len, --len2, ++comma;
if( comma == 4 )
{
comma = 1;
//tmp2[len2] = ',';
--len2;
}
tmp2[len2] = tmp[len];
}
return sign + tmp2 + decimal;
}
char takeInChr( const std::string& msg )
{
std::cout << msg << std::flush;
std::string reply;
getline( std::cin, reply );
if( reply.size() )
return reply[0];
// else ...
return 0;
}
bool more( const std::string& text )
{
if( tolower( takeInChr( "More " + text +
"(y/n) ? " ) ) == 'n' )
return false;
// else ...
return true;
}
////////////////////////////////////////////////////////////
#endif