Wednesday, 30 September 2009

Passing Variable arguments in functions

Sometimes it becomes necessary to have variable number of arguments in the function. One way is to overload the function but that may be unnecessary for simple logic. We can use access variable-argument lists macros in the functions. Here is a simple example:





//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//Program to show how to use variable number of arguments

#include<iostream>
#include <stdarg.h> //needed for va_ macros
using namespace std;

//List Should be terminated by -1 in our case
int Add(int a,...)
{

int
total = a;
int
l_ParamVal=0;

//Declare a va_list macro and initialize it with va_start
va_list l_Arg;
va_start(l_Arg,a);

while
((l_ParamVal = va_arg(l_Arg,int)) != -1)
{

total+= l_ParamVal;
}


va_end(l_Arg);
return
total;
}


int
main()
{

cout<<"Result of Add(2) = "<<Add(2, -1)<<endl;
cout<<"Result of Add(2, 3) = "<<Add(2, 3, -1)<<endl;
cout<<"Result of Add(2, 3, 31) = "<<Add(2, 3, 31, -1)<<endl;
cout<<"Result of Add(2, 3, 31, 77) = "<<Add(2, 3, 31, 77, -1)<<endl;

cout<<endl;
return
0;
}

These type of functions that take variable number of arguments are also referred to as 'Variadic Functions'. See more details here.

The output is as follows:

Friday, 25 September 2009

Passing unnamed arguments in functions

It is possible to pass an unnamed argument in C++ function. The unnamed argument indicates that argument is unused. Typically unnamed arguments arise from the simplification of code or from planning ahead for extensions. In either case, leaving the argument in place, although unused, ensures that the callers are not affected by the change. Simple example as follows:



//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//Simple example of unnamed arguments
#include<iostream>

using namespace
std;

void
someFunc(int a, int)
{

cout<<"Only a is defined to "<<a<<endl;
cout<<"The second argument is dummy"<<endl;
}


int
main()
{

someFunc(15, 100); //100 is dummy

cout<<endl;
return
0;
}






The output is as follows:

Tuesday, 22 September 2009

Converting Decimal Integer to Hexadecimal String using C++

I often encounter situations where I want to convert an Integer value to a Hexadecimal value. Now if it was just for storing, it doesnt really matter as internally decimal and hex values are the same. If it was just printing, its again very straightforward. But the problem I have is to convert it into string value (or chars[]) and use them later. I found a simple program to do this. Here it is:



//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//Example of program that does int to hex string
//Adapted from http://www.dreamincode.net/forums/showtopic19694.htm
#include<iostream>
#include <stack>

using namespace
std;

string int2hex(unsigned int dec)
{

int
i = 0;
stack <int>remainder;
string hex, temp;
char
hexDigits[] = { "0123456789abcdef" };

if
(dec == 0)
hex = hexDigits[0];

while
(dec != 0)
{

remainder.push(dec % 16);
dec /= 16;
++
i;
}


while
(i != 0)
{

if
(remainder.top() > 15)
{

temp = int2hex(remainder.top());
hex += temp;
}

hex.push_back(hexDigits[remainder.top()]);
remainder.pop();
--
i;
}

return
hex;
}



int
main()
{

unsigned int
dec = 4294967295;
string hex = int2hex(dec);
cout<<"dec = "<<dec<<" and hex = "<<hex.c_str()<<endl;
dec = 123456789;
hex = int2hex(dec);
cout<<"dec = "<<dec<<" and hex = "<<hex.c_str()<<endl;
dec = 100;
hex = int2hex(dec);
cout<<"dec = "<<dec<<" and hex = "<<hex.c_str()<<endl;
dec = 15;
hex = int2hex(dec);
cout<<"dec = "<<dec<<" and hex = "<<hex.c_str()<<endl;
dec = 0;
hex = int2hex(dec);
cout<<"dec = "<<dec<<" and hex = "<<hex.c_str()<<endl;
cout<<endl;
return
0;
}





The output is as follows:

Thursday, 17 September 2009

Converting normal string/char to wide string/char and vice versa

When you are playing with wide charachters in C++, you sometimes need to covert it into normal charachters and vice versa. Here is a simple program that I picked up from somewhere but cant remember.



//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//Program to convert from Wide to Narrow strings and Vice Versa
#include<iostream>
#include <sstream>

using namespace
std;

wstring widen( const string& str)
{

wostringstream wstm ;
const
ctype<wchar_t>& ctfacet = use_facet< ctype<wchar_t> >( wstm.getloc() ) ;
for
( size_t i=0 ; i<str.size() ; ++i )
wstm << ctfacet.widen( str[i] ) ;
return
wstm.str() ;
}


string narrow( const wstring& str )
{

ostringstream stm ;
const
ctype<char>& ctfacet = use_facet< ctype<char> >( stm.getloc() ) ;
for
( size_t i=0 ; i<str.size() ; ++i )
stm << ctfacet.narrow( str[i], 0 ) ;
return
stm.str() ;}

int
main()
{
{

const
wchar_t* wcstr = L"asdfg12345" ;
string cstr = narrow(wcstr);
cout <<"\nOutput from wide to narrow = "<< cstr.c_str() << endl ;
}
{

const
char* cstr = "zxcvb67890" ;
wstring wcstr = widen(cstr);
wcout << L"\nOutput from narrow to wide = "<<wcstr.c_str() << endl ;
}

return
0;
}






The output is as follows:


Sunday, 13 September 2009

Advanced features of C++ functions

There are 3 advanced features of C++ functions as compared to C. They are Call by Reference, Function Overloading and Default Arguments. You can read more about them here.

A simple program showing all the three features as follows:



//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//Example of pointer to const and const pointer
#include<iostream>

using namespace
std;

//Call by reference
void swap(int& a, int &b)
{

int
temp = a;
a = b;
b = temp;
}


//Overloaded function: Call by reference (pointers)
void swap(int *a, int *b)
{

int
temp = *a;
*
a = *b;
*
b = temp;
}


//Pass by value with Default arguments
void doSwap(int a, int b = 1)
{

swap(a,b);
cout<<"After Local Swap: a = "<< a <<" b = "<< b <<endl;
}


int
main()
{

int
a = 10, b = 17;
cout<<"Before Swap : a = "<< a <<" b = "<< b <<endl;
swap(a, b);
cout<<"After Swap 1: a = "<< a <<" b = "<< b <<endl;
swap(&a, &b);
cout<<"After Swap 2: a = "<< a <<" b = "<< b <<endl;
doSwap(a, b);
doSwap(a);
cout<<"After DoSwap: a = "<< a <<" b = "<< b <<endl;

return
0;
}






The output is as follows:


Thursday, 10 September 2009

Using Wide Charachters in C++

The normal 'char' is 8 bits. There is a 'wide char' (wchar_t) that is generally 16 bits. The width of wchar_t is compiler specific and can be as small as 8 bits. It is therefore recommended that it should not be used for creating portable programs.

A simple example as follows:


//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//Simple example of printing and comparing wide charachters
#include<iostream>

using namespace
std;

int
main()
{

wchar_t
wide_charachter;
wide_charachter = L'c';
//using wcout for printing
wcout<<"Wide Output of wide_charachter = "<<wide_charachter<<endl;

wstring wide_string; //wide string
wide_string = L"A wide string";
wcout<<"Wide Output of wide_string = "<<wide_string.c_str()<<endl;

wstring new_wide_string(L"Another wide string");

//comparing strings
if(wcscmp(new_wide_string.c_str(),wide_string.c_str())== 0)
cout<<"new_wide_string == wide_string"<<endl;
else

cout<<"new_wide_string != wide_string"<<endl;

if
(wcscmp(new_wide_string.c_str(),L"Another wide string")== 0)
cout<<"new_wide_string == L\"Another wide string\""<<endl;

return
0;
}




The output is as follows:

Tuesday, 8 September 2009

Getting Date and Time in C++ on Windows

The program example below shows three aproaches to get the date and time. MSDN references are embedded in the program.


#include<iostream>
#include<time.h> //For approach1 and approach3
#include <Windows.h> //For approach 2

using namespace
std;

void
approach1(void)
{

char
dateStr [9];
char
timeStr [9];
//http://msdn.microsoft.com/en-us/library/585kfedd(VS.80).aspx
_strdate_s( dateStr);
//http://msdn.microsoft.com/en-us/library/yb2bth04(VS.80).aspx
_strtime_s( timeStr );
cout<<"\nApproach 1"<<endl;
cout<<"Current date is: "<<dateStr<<endl;
cout<<"Current time is: "<<timeStr<<endl;
}


void
approach2(void)
{

SYSTEMTIME systemTime;
//http://msdn.microsoft.com/en-us/library/ms724390(VS.85).aspx
GetSystemTime(&systemTime);
cout<<"\nApproach 2"<<endl;
cout<<"Current date is: "<<systemTime.wMonth<<"/"<<systemTime.wDay<<"/"<<systemTime.wYear<<endl;
cout<<"Current time is: "<<systemTime.wHour<<":"<<systemTime.wMinute<<":"<<systemTime.wSecond<<endl;
}


void
approach3(void)
{

//http://www.daniweb.com/forums/thread64803.html
char buffer[BUFSIZ] = { '\0' } ;
time_t now = time( &now ) ;
struct
tm local_time;
//http://msdn.microsoft.com/en-us/library/a442x3ye(VS.80).aspx
localtime_s( &local_time, &now ) ;
cout<<"\nApproach 3"<<endl;
//http://msdn.microsoft.com/en-us/library/fe06s4ak(VS.71).aspx
strftime( buffer, BUFSIZ, "%m/%d/%Y", &local_time ) ;
cout<<"Current date is: "<< buffer << endl ;
strftime( buffer, BUFSIZ, "%H:%M:%S", &local_time ) ;
cout<<"Current time is: "<< buffer << endl ;
}


int
main()
{

approach1();
approach2();
approach3();
return
0;
}






The output is as follows:

Friday, 4 September 2009

Changing objects in 'const member functions' via Mutable

We saw last time an example of 'Const Member Functions' (also known as 'Inspectors'). In contrast the member functions without the const suffix are known as 'non-const member functions' or 'mutators'.

Sometimes it may be necessary to modify a data member (variable or object in your class) in a const member function. There are two approaches to do that. One is to use the const_cast and the other to use 'mutable'. I use both the approaches in the example below:



//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//This example shows how to change objects in const member functions
#include<iostream>

using namespace
std;

class
ABC
{

public
:
int
func1(int a, int b);
int
func2(int a, int b) const;
private
:
int
x;
mutable
int y;
};


int
ABC::func1(int a, int b)
{

x = a, y = b;
cout<<"x = "<<x<<" and y = "<<y<<endl;
return
0;
}


int
ABC::func2(int a, int b) const
{

//x = a; - COMPILE ERROR because its const
int *temp = const_cast<int*>(&x); //Removing the const
*temp = a; //OK now
y = b; //OK because its defined as mutable
cout<<"x = "<<x<<" and y = "<<y<<endl;
return
0;
}


int
main()
{

ABC abc;
abc.func1(3, 7);
abc.func2(20, 40);
return
0;
}



The output is as follows: