Monday, August 18, 2008

String Class in cpp(Standard cpp strings)

Here is how to test the string class already present in cpp.
To use simple strings u have to include <iostream>. For example consider the program,
#include <iostream>
#include <conio.h>
using namespace std;

int main()
{
    string word="hello";
    cout<<word;
    getch();
   
}

There are various functions and operators in this string class. These operators are present in string -
=        assignment
+ , +=  concatenation etc
 == , != . < , <= , >= , >   equality etc.
[]       subscription
<<     output
>>     input

Following are the functions which are present in the string class

Consider the program:
#include <iostream>
#include <conio.h>
using namespace std;
int main( )
{
    string s1 ( "kicit" ) ;
    string s2 ( "Nagpur" ) ;

    cout << endl ;
    cout << "String s1: " ;
    cout<<s1;
    cout << "\nLength of string s1: " << s1.length( ) << endl ;

    cout << "\nString s2: " ;
    cout<<s2;

    string s3 = s1;// copy
    cout<<"\ns3="<<s3;

    s3=s3+s1;
    cout << "\nString s3 after concatenation: " ;
    cout<<s3;

    if ( s1.compare(s2)== 0 )
        cout << "\nThe strings s1 and s2 are similar" << endl ;
    else
        cout << "\nThe strings s1 and s2 are not similar" << endl ;
        getch();
}



Some more cases of string:
string s1;                                    //s1 contains 0 character
string s2 =  "New York";            
//s1 contains 8 character
string s3(60,'*');                          //s1 contains 60 asterisk
string s4=s3;                             //s1 contains 60 asterisk
string s5(s2, 4,2);                      //s1 contains 2 characters , i.e. "Yo"
Some more:
string s= "ABCDEFG";
getline(s,cin);           // reads the entire string with spaces into s
char c = s[2];           // c = C;
s[4]='*';                   //s= "ABCD*FG";

const char * cs = s.c_str();   // CONVERT s TO C STRING

Using find, substr(), erase() and replace
s6=s+"HIJK";
s4= s6.substr();
s6.erase(4, 2);
s6.replace(5,2,  "xyz")
s6 = "Missisippi River";












hello i am not hter
constructors 1.

#include #include using namespace std; int main () { char *line = "short line for testing"; // with no arguments string s1; s1 = "Anatoliy"; cout << "s1 is: " << s1 << endl; // copy constructor string s2 (s1); cout << "s2 is: " << s2 << endl; // one argumen string s3 (line); cout << "s3 is: " << s3 << endl; // first argumen C string // second number of characters string s4 (line,10); cout << "s4 is: " << s4 << endl; // 1 - C++ string // 2 - start position // 3 - number of characters string s5 (s3,6,4); // copy word 'line' from s3 cout << "s5 is: " << s5 << endl; // 1 - number characters // 2 - character itself string s6 (15,'*'); cout << "s6 is: " << s6 << endl; // 1 - start iterator // 2 - end iterator string s7 (s3.begin(),s3.end()-5); cout << "s7 is: " << s7 << endl; // you can instantiate string with assignment string s8 = "Anatoliy"; cout << "s8 is: " << s8 << endl; return 0; } OUTPUT: // s1 is: Anatoliy // s2 is: Anatoliy // s3 is: short line for testing // s4 is: short line // s5 is: line // s6 is: *************** // s7 is: short line for te // s8 is: Anatoliy getline 1.
/* 1 getline ( intut_stream, str, delim ); Extracts characters from intut_stream and stores them in str until s.max_size() characters have been extracted, the end of file occurs, or delim is encountered, in which case delim is extracted from istr but is not stored in s 2 getline( Iter, str ) Inputs a string value for str as in the preceding func� tion with delim = */
#include #include #include #include using namespace std; int main () { string str; cout << "Enter string (EOL = $) : "; getline (cin, str, '$'); cout << "Str is : " << str << endl; ifstream In("data.dat"); vector v; cout << endl << "Read data from file" << endl; while ( ! In.eof() ) { getline (In, str); v.push_back(str); } copy (v.begin(),v.end(), ostream_iterator(cout,"\n")); cout << endl; return 0; } OUTPUT: // Enter string (EOL = $) : Str is : first line // second line$ // // Read data from file // file: "data.dat" // second line // last line << >> operators 1.
#include #include using namespace std; int main () { string str; cout << "Enter string for testing : "; cin >> str; cout << "\nString is : " << str << endl; cout << "Enter string for testing " << "(d to quit) : "; while ( cin >> str ) { cout << endl; cout << "String is : " << str << endl; cout << "Enter string for testing " << "(d to quit) : "; } return 0; } OUTPUT: // Enter string for testing : first // String is : first // Enter string for testing (d to quit) : second // String is : second // Enter string for testing (d to quit) : third // String is : third // Enter string for testing (d to quit) : + += = operators 1.
#include #include using namespace std; int main () { string str = "Hello"; cout << "str is : " << str << endl; str += ","; str += ' '; cout << "str is : " << str << endl; string s; s = str + "World"; cout << "s is : " << s << endl; char ch = '!'; s += ch; cout << "s is : " << s << endl; return 0; } OUTPUT: // str is : Hello // str is : Hello, // s is : Hello, World // s is : Hello, World! append 1.
#include #include using namespace std; int main () { string str = "Nobody is perfect"; string s = ""; // empty string char *ch = "abcdef"; // append string str at the end of s; // return s // appends at the end of s a copy of the n characters // in str, starting at position pos; if n is too // large, characters are copied only until the end // of str is reached; // returns s s.append(str,0,6); cout << "s is : " << s << endl; // appends copies of the characters in the range [inpIt1, // inpIt2] to s; returns s string::iterator inpIt1 = str.begin()+6; //start from ' is' string::iterator inpIt2 = str.end(); s.append(inpIt1,inpIt2); cout << "s is : " << s << endl; // appends three ! s.append(3,'!'); cout << "s is : " << s << endl; // appends the first n characters in ch at the end // of s; returns s s.append(ch,3); cout << "s is : " << s << endl; // appends charArray at the end of s; returns s s.append(ch,3); cout << "s is : " << s << endl; return 0; } OUTPUT: // s is : Nobody // s is : Nobody is perfect // s is : Nobody is perfect!!! // s is : Nobody is perfect!!!abc // s is : Nobody is perfect!!!abcabc assign 1.
#include #include using namespace std; int main () { string str = "Nobody is perfect"; string s = ""; char *ch = "Robert Frost"; // assigns a copy of str to s; returns s s.assign(str); cout << "s is : " << s << endl; // assigns to s a copy of the n characters in str, start� // ing at position 10: if n is too large, characters are // copied only until the end of str is reached: returns s s.assign(str,10,7); // perfect cout << "s is : " << s << endl; // assigns to s a string consisting of the first n charac� // ters in ch: returns s s.assign(ch,6); cout << "s is : " << s << endl; // assigns to s a copy of ch: returns s s.assign(ch); cout << "s is : " << s << endl; // assigns to s a string consisting of the characters in // the range str.begin(), str.end(); returns s s.assign(str.begin(),str.end()); cout << "s is : " << s << endl; // assigns to s a string consisting of n copies of ch; // returns s s.assign(17,'*'); cout << "s is : " << s << endl; return 0; } OUTPUT: // s is : Nobody is perfect // s is : perfect // s is : Robert // s is : Robert Frost // s is : Nobody is perfect // s is : ***************** at 1.
// returns s[pos]
#include #include using namespace std; int main () { string s = "Nobody is perfect"; // Returns s[pos] for ( int pos = 0; pos < s.length(); ++pos ) cout << s.at(pos) << " "; cout << endl; return 0; } OUTPUT: // N o b o d y i s p e r f e c t begin 1.
// Returns an iterator positioned at the // first character in a string
#include #include using namespace std; int main () { string str = "C++ is best computer language"; string::iterator It = str.begin(); while ( It != str.end() ) { if ( *It == ' ' ) *It = '\n'; cout << *It++; } cout << endl; return 0; } OUTPUT: // C++ // is // best // computer // language c_str 1.
// returns (the base address of) a char // array containing the characters stored in s, // terminated by a null character.
#include #include using namespace std; int main () { string str = "Anatoliy"; char *ary = new char[str.length()+1]; // strcpy ( ary, str ); that is wrong way strcpy ( ary, str.c_str() ); // that is correct cout << ary << endl; return 0; } OUTPUT: // Anatoliy capacity 1.
// returns the size (of type size_type) // of the storage allocated in string
#include #include using namespace std; int main () { string str = "C++ is best computer language"; string::size_type cap; cap = str.capacity(); cout << "Capacity of str is: " << cap << endl; cout << "Size of str is : " << str.size() << endl; cout << "Length of str is : " << str.length() << endl; cout << "Resize the str for 50 character" << endl; str.resize(50); cap = str.capacity(); cout << "Capacity of str is: " << cap << endl; cout << "Size of str is : " << str.size() << endl; cout << "Length of str is : " << str.length() << endl; return 0; } OUTPUT: // Capacity of str is: 32 // Size of str is : 29 // Length of str is : 29 // Resize the str for 50 character // Capacity of str is: 64 // Size of str is : 50 // Length of str is : 50 compare 1.
#include #include using namespace std; int main () { string str1 = "string"; string str2 = "String"; string str3 = "second string"; char ch[] = "first string"; cout << "string str1 is : " << str1 << endl; cout << "string str2 is : " << str2 << endl; cout << "char ary ch is : " << ch << endl; cout << "string str3 is : " << str3 << endl; cout << endl; // compare str1 and str2 cout << "1." << endl; size_t comp = str1.compare(str2); cout << "String str1 is "; ( comp == 0 ) ? cout << "equal" : cout << "not equal"; cout << " to string str2" << endl; // compare str1 and literal string "string" cout << "2." << endl; comp = str1.compare("string"); cout << "String str1 is "; ( comp == 0 ) ? cout << "equal" : cout << "not equal"; cout << " to array of char \"string\"" << endl; // 3. and 4. doesn't work with Microsoft // Visual Studio compiler // compare str3 start from pos 7 to 5 // with str1 cout << "3." << endl; comp = str3.compare(str1,7,5); cout << "Part of string str3 is "; ( comp == 0 ) ? cout << "equal" : cout << "not equal"; cout << " to str1" << endl; // compare str3 start from pos 7 // with literal string "string" cout << "4." << endl; comp = str3.compare("string",7); cout << "Part of string str3 is "; ( comp == 0 ) ? cout << "equal" : cout << "not equal"; cout << " to C string \"string\"" << endl; // next 4 'compare' functions // doesn't work with GNU compiler cout << "5." << endl; comp = str1.compare(6,10,ch); cout << "String str1 is "; ( comp == 0 ) ? cout << "equal" : cout << "not equal"; cout << " to part of char ary \"first string\"" << endl; cout << "6." << endl; comp = str1.compare(0,3,str3); cout << "Part of str1 is "; ( comp == 0 ) ? cout << "equal" : cout << "not equal"; cout << " to string \"second string\"" << endl; cout << "7." << endl; comp = str1.compare(1,3,str2,1,3); cout << "String str1 is "; ( comp == 0 ) ? cout << "equal" : cout << "not equal"; cout << " to part of string \"second string\"" << endl; cout << "8." << endl; comp = str1.compare(1,3,str2,1,3); cout << "String str1 is "; ( comp == 0 ) ? cout << "equal" : cout << "not equal"; cout << " to part of string \"second string\"" << endl; return 0; } OUTPUT: GNU compiler // string str1 is : string // string str2 is : String // char ary ch is : first string // string str3 is : second string // // 1. // String str1 is not equal to string str2 // 2. // String str1 is equal to array of char "string" // 3. // Part of string str3 is equal to str1 // 4. // Part of string str3 is equal to C string "string" // 5. // 6. // 7. // 8. OUTPUT: Microsoft Visual Studio compiler // string str1 is : string // string str2 is : String // char ary ch is : first string // string str3 is : second string // // 1. // String str1 is not equal to string str2 // 2. // String str1 is equal to array of char "string" // 3. // 4. // 5. // String str1 is not equal to part of char ary "first // string" // 6. // Part of str1 is not equal to string "second string" // 7. // String str1 is equal to part of string "second string" // 8. // String str1 is equal to part of string "second string" // Press any key to continue copy 1.
#include #include using namespace std; int main () { string str = "First Name: Robert"; char fname[255]; cout << "str is: " << str << endl; int n = str.find(':'); str.copy(fname, // copy to array n+1, // how many char 0); // start position from str // must terminate fname with '\0'; fname[n+1] = 0; cout << "fname is: " << fname << endl; return 0; } OUTPUT: // str is: First Name: Robert // fname is: First Name: empty 1.
#include #include using namespace std; int main () { string str = "*******"; while ( ! str.empty() ) { cout << str << endl; str.erase(str.end()-1); } cout << endl; return 0; } OUTPUT: // ******* // ****** // ***** // **** // *** // ** // * end 1.
// returns an iterator porsitioned immediately // after the last character in string
#include #include using namespace std; int main () { string s; string str = "*************************"; size_t pos = str.length(); while ( pos ) { s.assign ( str.begin(),str.end() - pos+1); cout << s << endl; pos -= 5; } return 0; } OUTPUT: // * // ****** // *********** // **************** // ********************* erase 1.
#include #include #include using namespace std; int main () { string str, s; for ( char ch = 'a'; ch <= 'z'; ch++ ) str.append(1,ch); s = str; cout << "str is: " << str << endl; cout << "s is: " << str << endl; // removes 13 characters from the beginning str.erase(0,13); cout << "Erased range fron str : " << str << endl; // removes 13 characters starts from 14 str = s.erase(13,13); cout << "Erased range from s : " << str << endl; // removes one character pointed by s.begin() cout << endl << "Erase one, second character from s" << endl; s.erase(s.begin()+1); cout << "s is: " << s << endl; // removes range of characters s.erase(s.begin(),s.begin()+4); cout << "s is: " << s << endl; return 0; } OUTPUT: // str is: abcdefghijklmnopqrstuvwxyz // s is: abcdefghijklmnopqrstuvwxyz // Erased range fron str : nopqrstuvwxyz // Erased range from s : abcdefghijklm // // Erase one, second character from s // s is: acdefghijklm // s is: fghijklm find 1.
#include #include #include using namespace std; int main () { string str("C++ is best language"); int pos1, pos2; // size_t or size_type // work not correct // search for first string "best" inside of str // default position is 0 pos1 = str.find ("best"); cout << "Word best is found on position " << pos1+1 << endl; // if pattern is not found - return -1 pos2 = str.find ("best",pos1+1); cout << "Word best is found on position " << pos2+1 << endl; // search for first occurrence of character pos1 = str.find('g'); cout << "First character 'g' found on position " << pos1 << endl; // search for first occurrence of string string s = "is"; pos1 = str.find (s); cout << "Word 'is' is found on position " << pos1+1 << endl; return 0; } OUTPUT: // Word best is found on position 8 // Word best is found on position 0 // First character 'g' found on position 15 // Word 'is' is found on position 5 find_first_not_of 1.
#include #include using namespace std; int main () { string str("C++ is best language"); cout << "str is: " << str << endl; int n = str.find_first_not_of("aeiouAEIOU"); cout << "First consonant found at " << n+1 << " position" << endl; return 0; } OUTPUT: // str is: C++ is best language // First consonant found at 1 position find_first_not_of 2.
#include #include using namespace std; int main () { string str("C++ is best language"); cout << "str is: " << str << endl; // search first not ' ', // start from position 7 int n = str.find_first_not_of(' ',7); cout << "first not of space character " << "found at position " << n+1 << endl; return 0; } OUTPUT: // str is: C++ is best language // first not of space character found at position 8 find_first_not_of 3.
#include #include using namespace std; int main () { string str("C++ is best language"); string s = "C++"; cout << "str is: " << str << endl; // search character from pattern // using the first x ch�racters in pattern. // the value position must be given int n = str.find_first_not_of("CBCD",0,3); cout << "first not 'C' is found at position " << n+1 << endl; // search first not of // pattern is string n = str.find_first_not_of(s); cout << "first not of C++ is found " << "at position " << n+1 << endl; return 0; } OUTPUT: // str is: C++ is best language // first not 'C' is found at position 2 // first not of C++ is found at position 4 find_first_of 1.
#include #include using namespace std; int main () { string str("C++ is best language"); string s = "be"; cout << "str is: " << str << endl; // search be start from position 2 // if position is ommited - default is 0 int n = str.find_first_of(s,2); cout << "first 'be' found at position " << n+1 << endl; // same as above but search for character n = str.find_first_of('l'); cout << "first character 'l' found at " << "position " << n+1 << endl; // search 'first of' for the characters in // charary char charary[] = " bea"; cout << "charary[] = \" bea\"" << endl; n = str.find_first_of(charary,0); cout << "first character from charary " << "found at position " << n+1 << endl; cout << "Note: position 4 is space" << endl; // same as above but third argumen is // number of character from which searching // starts // this variant of find_first_of dosn't // work properly with GNU compiler n = str.find_first_of(" bae",0,3); cout << "first character from charary " << "found at position " << n+1 << endl; return 0; } OUTPUT: // str is: C++ is best language // first 'be' found at position 8 // first character 'l' found at position 13 // charary[] = " bea" // first character from charary found at position 4 // Note: position 4 is space // first character from charary found at position 4 find_last_not_of 1.
#include #include using namespace std; int main () { string str("C++ is best language"); string s = "langue"; int pos = str.length()-1; cout << "str is: " << str << endl; // returns the highest position <= pos of a character // in str that does not match any charcter in s; // returns nopos if there is no such position: // npos is the default value for pos int n = str.find_last_not_of(s, pos); cout << "last_not_of 'langue' found at position " << n+1 << endl; // same as above but search for single character n = str.find_last_not_of('e'); cout << "last_not_of 'e' found at position " << n+1 << endl; char ary[] = "be"; // seawrch for occurence last_not_of // from pattern ary in str n = str.find_last_not_of(ary); cout << "last_not_of 'be' found at position " << n+1 << endl; return 0; } OUTPUT: // str is: C++ is best language // last_not_of 'langue' found at position 12 // last_not_of 'e' found at position 19 // last_not_of 'be' found at position 19 find_last_of 1.
#include #include using namespace std; int main () { string str("C++ is best language"); string s = "g"; cout << "str is: " << str << endl; cout << "s is: " << s << endl; int n = str.find_last_of(s); cout << "last_of '" << s << "' faund" << " at position " << n+1 << endl; n = str.find_last_of(' '); cout << "last_of ' ' faund" << " at position " << n+1 << endl; n = str.find_last_of(" la"); cout << "last_of \" la\" faund" << " at position " << n+1 << endl; return 0; } OUTPUT: // str is: C++ is best language // s is: g // last_of 'g' faund at position 19 // last_of ' ' faund at position 12 // last_of " la" faund at position 18 insert 1.
#include #include using namespace std; int main () { string str = "C++ language"; string s = "is best"; char ch[] = "C++ language"; cout << "str is: " << str << endl; cout << "s is: " << s << endl; cout << "ch is: " << s << endl; // insert a copy of s into str // at position pos; string::size_type pos = 4; str.insert(pos,s); cout << "str is: " << str << endl; // insert a copy of ch into str at // the position specified by iterator // return an iterator positioned at // this copy int n = str.find('l'); str.insert(str.begin() + n,' '); cout << "str is: " << str << endl; // like above but n x copies of char str.insert(str.end(),3,'!'); cout << "str is: " << str << endl; // insert 4 char from ch into s // at the position 0 s.insert(0,ch,4); cout << "s is: " << s << endl; // insert 8 characters from str // start from position n ('langu...') // into s at position x (end string) n = str.find('l'); int x = s.length(); s.insert(x,str,n,8); cout << "s is: " << s << endl; n = s.find('l'); s.insert(s.begin()+n,' '); cout << "s is: " << s << endl; // insert range (begin - begin+7) of str // into s at position begin+4 s.insert(s.begin()+4,str.begin(),str.begin()+7); cout << "s is: " << s << endl; return 0; } OUTPUT: // str is: C++ language // s is: is best // ch is: is best // str is: C++ is bestlanguage // str is: C++ is best language // str is: C++ is best language!!! // s is: C++ is best // s is: C++ is bestlanguage // s is: C++ is best language // s is: C++ C++ is is best language length 1.
#include #include using namespace std; int main () { string str = "C++ is best computer language"; cout << "str is: " << str << endl; cout << "Length of str is : " << str.length() << endl; return 0; } OUTPUT: // str is: C++ is best computer language // Length of str is : 29 max_size 1.
// returns a reverse iterator positioned // at the last character in string
#include #include using namespace std; int main () { string str = "C++ is best computer language"; cout << "str is: " << str << endl; cout << "max_size of str is: " << str.max_size() << endl; return 0; } OUTPUT: // str is: C++ is best computer language // max_size of str is: 4294967294 rbegin 1.
#include #include using namespace std; int main () { string str = "C++ is best computer language"; cout << "str is: " << str << endl; // usual iterator doesn't work string::reverse_iterator It = str.rbegin(); while ( It != str.rend() ) cout << *It++; cout << endl; return 0; } OUTPUT: // str is: C++ is best computer language // egaugnal retupmoc tseb si ++C replace 1.
#include #include using namespace std; int main () { string str = "STL is created from Dennis Ritchie"; string s1 = "was"; string s2 = "developed"; string s3 = "Stepanov alexander"; cout << "str is: " << str << endl; cout << "replace 'is' for 'was'" << endl; str.replace(4, // start position in str 2, // how many characters s1); // source for replasment cout << "str is: " << str << endl; cout <<"replace 'created' for 'developed'" << endl; int n = str.find('c'); // pos of 'created' int x = str.find("from") -1; str.replace(str.begin()+n,// start pointer str.begin()+x, // end pointer s2); // source cout << "str is: " << str << endl; cout << "replace 'Dennis' for 'alexander'" << endl; int x1 = str.find('D'); // search Dennis int x2 = str.find(' ',x1+1); // space after int y1 = s3.find("alex"); // search 'alex' int y2 = strlen("alexander"); str.replace(x1, // start position in str x2-x1, // how characters to replace s3, // source for replacement y1, // start positio from source y2); // how chracter start from y1 cout << "str is: " << str << endl; cout << "replace 'from' for 'by'" << endl; char ary[] = "bytes"; n = str.find("from"); // same variant possible with iterators // instead of number of position str.replace(n, // start position in str 4, // how many characters ary, // source 2); // first 2 characters from source cout << "str is: " << str << endl; cout << "replace 'a' for 'A' (alexander)" << endl; n = str.find("alexander"); str.replace(n, // start position in str 1, // how character(s) 1, // how many copies of character 'A'); // character for replasment cout << "str is: " << str << endl; cout << "replace 'Ritchie' for 'Stepanov'" << endl; x1 = str.find('R'); y1 = s3.find(' '); str.replace(str.begin()+x1, // start pointer str.end(), // to the end of str s3.begin(), // start pointer from source s3.begin()+y1 // end pointer from ); // source cout << "str is: " << str << endl; return 0; } OUTPUT: // str is: STL is created from Dennis Ritchie // replace 'is' for 'was' // str is: STL was created from Dennis Ritchie // replace 'created' for 'developed' // str is: STL was developed from Dennis Ritchie // replace 'Dennis' for 'alexander' // str is: STL was developed from alexander Ritchie // replace 'from' for 'by' // str is: STL was developed by alexander Ritchie // replace 'a' for 'A' (alexander) // str is: STL was developed by Alexander Ritchie // replace 'Ritchie' for 'Stepanov' // str is: STL was developed by Alexander Stepanov reverse 1.
#include #include using namespace std; int main () { string str = "Anatoliy Urbanskiy"; cout << str.reverse() << endl; return 0; } OUTPUT: resize 1.
// if <=s.size(), truncates rightmost // character in s to make it of size n; otherwise, adds // copies of character ch to end of s to increase it size // to n, or adds a default character value (usually a // blank) if ch is omitted; return type is void
#include #include using namespace std; int main () { string str = "Alexander Stepanov"; cout << "str is: " << str << endl; cout << "size of str is: " << str.size() << endl; str.resize(11); cout << "after str.resize(11)" << endl; cout << "str is: " << str << endl; cout << "size of str is: " << str.size() << endl; str.resize(20,'.'); cout << "after str.resize(20,'.')" << endl; cout << "str is: " << str << endl; cout << "size of str is: " << str.size() << endl; return 0; } OUTPUT: // str is: Alexander Stepanov // size of str is: 18 // after str.resize(11) // str is: Alexander S // size of str is: 11 // after str.resize(9,'.') // str is: Alexander S......... // size of str is: 20 rfind 1.
#include #include using namespace std; int main () { string str = "We go step by step to the target"; string s1 = "step"; cout << "str is: " << str << endl; cout << "s1 is: " << s1 << endl; cout << "int n1 = str.find(s1)" << endl; int n1 = str.find(s1); cout << "n1 = " << n1+1 << endl; cout << "int n2 = str.rfind(s1)" << endl; int n2 = str.rfind(s1); cout << "n2 = " << n2+1 << endl; cout << "n3 = str.rfind(s1,n2-1)" << endl; int n3 = str.rfind(s1,n2-1); cout << "n3 = " << n3+1 << endl; cout << "n1 = str.rfind('t')" << endl; n1 = str.rfind('t'); cout << "n1 = " << n1+1 << endl; cout << "n2 = str.rfind('t',n1-1)" << endl; n2 = str.rfind('t',n1-1); cout << "n2 = " << n2+1 << endl; char ch[] = "step"; cout << "char ch[] = \"step\"" << endl; cout << "n1 = str.rfind(ch)" << endl; n1 = str.rfind(ch); cout << "n1 = " << n1+1 << endl; cout << "n2 = str.rfind(\"stabc\",10,2)" << endl; n2 = str.rfind("stabc", // pattern 10, // start position 2); // for first 2 char // in pattern cout << "n2 = " << n2+1 << endl; return 0; } OUTPUT: // str is: We go step by step to the target // s1 is: step // int n1 = str.find(s1) // n1 = 7 // int n2 = str.rfind(s1) // n2 = 15 // n3 = str.rfind(s1,n2-1) // n3 = 7 // n1 = str.rfind('t') // n1 = 32 // n2 = str.rfind('t',n1-1) // n2 = 27 // char ch[] = "step" // n1 = str.rfind(ch) // n1 = 15 // n2 = str.rfind("stabc",10,2) // n2 = 7 size 1.
#include #include using namespace std; int main () { string str = "We go step by step to the target"; string::size_type size = str.size(); cout << "str is: " << str << endl; cout << "size of str = " << size << endl; return 0; } OUTPUT: // str is: We go step by step to the target // size of str = 32 substr 1.
// str.subsr(pos,n); // returns a copy of the substring consisting // of n characters from str, beginning at position pos // (default value 0); if n is too large or is omitted, // characters are copied only until the end of s is // reached
#include #include using namespace std; int main () { string str = "We go step by step to the target"; cout << "str is: " << str << endl; int n = str.find("step"); string s = str.substr(n); cout << "s is: " << s << endl; s = str.substr(n,12); cout << "s is: " << s << endl; return 0; } OUTPUT: // str is: We go step by step to the target // s is: step by step to the target // s is: step by step swap 1.
#include #include using namespace std; int main () { string str1 = "Robert"; string str2 = "Forest"; cout << "str1 is: " << str1 << endl; cout << "str2 is: " << str2 << endl; cout << endl; cout << "str1.swap(str2)" << endl; cout << endl; str1.swap(str2); cout << "str1 is: " << str1 << endl; cout << "str2 is: " << str2 << endl; return 0; } OUTPUT: // str1 is: Robert // str2 is: Forest // // str1.swap(str2) // // str1 is: Forest // str2 is: Robert

Stack ADT

Stacks are an elementary Data Structure where all interaction with the data is done through the looking at the first element. Stacks are last in first out (LIFO) data structures. It is named on the basis of how the elements are removed from it. Opposite to stack is queue, in which the last element is removed, the element which was most old item, and hence it is FIFO or first in first out data structure.

Stack Operations
There are two main operations on Stacks, Push and Pop.


  • Push - The push operation is used to insert an item into the stack. The name push comes from the fact that when an item is inserted into the stack it is put into the first element in the stack, so we think of it as lying on top of the stack.
  • pop - The pop operation is used to remove an item from the stack. Items are removed from the top of the stack first. 


Other operations

  • isEmpty - Tells whether stack is empty or not
  • top or peek - It returns the most recently added element to the stack but dont remove it.
  • isFull - If stack has array implementation, you can find this method as well.





Stack implementation
There are 2 ways in which stack can be implemented:

Applications of Stack



Thursday, August 14, 2008

Miscellaneous cases with printf

Strings

1. printf(5+Fascimile);
O
mile
2. printf(5+"Good Morning");
O
Morning
3. printf("%c", abcdefg[4]);
O.
e

Strings

static char s[]= "Oinks Grunts and Guffaws";

Now we see some results on this string:
1. *(&s[2])=s[2]=*(s+2)=*(2+s ) = n
2. strlen(s) = length of the string
so strlen(s)+s= last character of the string = \0 , whose ascii value is 0.
So when %c is used , \0 is printed and when %d is used 0 is printed.
3. when is printed with %d we get the base address of the string.
4. s+5 with %s prints ^Grunts and Guffaws, that is base address + 5 and rest of the string.

Now let i=0;
ch = s[++i]; // ch = s[1] i.e. i
ch=s[i++];  // ch=s[1] but i=2
ch =i++[s]  // ch = 2[s] = s[2 ] but i = 3.
ch = ++i[s]; // ++3[s] = ++s[3] = k+1 = l(ell)

Method Overriding

Suppose bc and dc have same functions:
In case of java for eg.
Method overriding occurs only when the names and the type signatures of the two
methods are identical. If they are not, then the two methods are simply overloaded. For
example, consider this modified version of the preceding example:
// Methods with differing type signatures are overloaded – not overridden.
class A {
int i, j;
A(int a, int b) {
i = a;
j = b;
}
// display i and j
void show() {
System.out.println("i and j: " + i + " " + j);
}
}
// Create a subclass by extending class A.
class B extends A {
int k;
B(int a, int b, int c) {
super(a, b);
k = c;
}
// overload show()
void show(String msg) {
System.out.println(msg + k);
}
}
class Override {
public static void main(String args[]) {
B subOb = new B(1, 2, 3);
subOb.show("This is k: "); // this calls show() in B
subOb.show(); // this calls show() in A
}
}
The output produced by this program is shown here:
This is k: 3
i and j: 1 2
The version of show( ) in B takes a string parameter. This makes its type signature
different from the one in A, which takes no parameters. Therefore, no overriding (or
name hiding) takes place.

Access specification

This topic tells when is contructor called and when not

1.formation of object(lolz)

2.passing objects to the function

class X
{
    int i;
public:
    X(int b)    {            cout<<"love";         i=b;     }
    void  set_i(int b){s=b;}
    put_i()     {         cout<<"i="<<     }
    X()//destructor     {         cout<<"hate"    }
}; // class over

void f(X ob)
{
    ob.set_i(2);//i is now 2
    ob.put_i();
}

int main()
{
    X o(1);//i is 1
    o.put_i();
    f(o);//i is now 2
    o.put_i();
    return 0;
}

This program produces this output
love
i=1
i=2
hate
i=1
hate
Notice that two calls to the destructor function are executed, but only one call is
made to the constructor function. 

As the output illustrates, the constructor function
is not called when the copy of o (in main() ) is passed to ob (within f() ). The reason
that the constructor function is not called when the copy of the object is made is easy to
understand. When you pass an object to a function, you want the current state of that
object. If the constructor is called when the copy is created, initialization will occur,
possibly changing the object. Thus, the constructor function cannot be executed when
the copy of an object is generated in a function call.

Although the constructor function is not called when an object is passed to a
function, it is necessary to call the destructor when the copy is destroyed. (The copy
is destroyed like any other local variable, when the function terminates.) Remember,
a new copy of the object has been created when the copy is made. This means that
the copy could be performing operations that will require a destructor function to
be called when the copy is destroyed. For example, it is perfectly valid for the copy to
allocate memory that must be freed when it is destroyed. For this reason, the destructor
function must be executed when the copy is destroyed.
To summarize: When a copy of an object is generated because it is passed to a
function, the object's constructor function is not called. However, when the copy of the
object inside the function is destroyed, its destructor function is called.
By default, when a copy of an object is made, a bitwise copy occurs. This means
that the new object is an exact duplicate of the original. The fact that an exact copy is
made can, at times, be a source of trouble. Even though objects are passed to functions
by means of the normal call-by-value parameter passing mechanism, which, in theory,
protects and insulates the calling argument, it is still possible for a side effect to occur
that may affect, or even damage, the object used as an argument. For example, if an
object used as an argument allocates memory and frees that memory when it is
destroyed, then its local copy inside the function will free the same memory when its
destructor is called. This will leave the original object damaged and effectively useless.
It is possible to prevent this type of problem by defining
the copy operation relative to your own classes by creating a special type of constructor
called a copy constructor.

3.When the objects are returned by the function

A function may return an object to the caller. For example, this is a valid C++ program:
// Returning objects from a function.
#include
using namespace std;
class myclass {
int i;
public:
void set_i(int n) { i=n; }
int get_i() { return i; }
};// end class
myclass f(); // return object of type myclass
int main()
{
myclass o;
o = f();
cout << o.get_i() << "\n";
return 0;
}
myclass f()
{
myclass x;
x.set_i(1);
return x;
}
When an object is returned by a function, a temporary object is automatically
created that holds the return value.
It is this object that is actually returned by the
function. After the value has been returned, this object is destroyed. The destruction of
this temporary object may cause unexpected side effects in some situations. For
example, if the object returned by the function has a destructor that frees dynamically
allocated memory, that memory will be freed even though the object that is receiving
the return value is still using it. There are ways to overcome this problem that involve
overloading the assignment operator and defining a copy constructor. 


 4.Initialised vs non initialised constructor

class X
{
    int a;
    public;
        X(){a=0;}
        X(int b){b=a;}
};

int main()
{
    X x;//con1
    X x(4);//con2
}

5.Copy constructor
It is important to understand that C++ defines two distinct types of situations in
which the value of one object is given to another. The first is assignment. The second is
initialization, which can occur any of three ways:

  •  When one object explicitly initializes another, such as in a declaration
  •  When a copy of an object is made to be passed to a function
  •  When a temporary object is generated (most commonly, as a return value)
The copy constructor applies only to initializations. For example, assuming a class
called myclass, and that y is an object of type myclass, each of the following statements
involves initialization.
myclass x = y; // y explicitly initializing x
func(y); // y passed as a parameter
y = func(); // y receiving a temporary, return object
Following is an example where an explicit copy constructor function is needed.
This program creates a very limited "safe" integer array type that prevents array
boundaries from being overrun. Storage for each array is allocated by the use of new,
and a pointer to the memory is maintained within each array object.
/* This program creates a "safe" array class. Since space for the array is allocated using new, a copy constructor is provided to allocate memory when one array object is used to initialize another.
*/
#include
#include
#include
using namespace std;
class array {
int *p;
int size;
public:
array(int sz) {
try {
p = new int[sz];
} catch (bad_alloc xa) {
cout << "Allocation Failure\n";
exit(EXIT_FAILURE);
}
size = sz;
}
~array() { delete [] p; }
// copy constructor
array(const array &a);
void put(int i, int j) {
if(i>=0 && i
}
int get(int i) {
return p[i];
}
};
// Copy Constructor
array::array(const array &a) {
int i;
try {
p = new int[a.size];
} catch (bad_alloc xa) {
cout << "Allocation Failure\n";
exit(EXIT_FAILURE);
}
for(i=0; i
}
int main()
{
array num(10);
int i;
for(i=0; i<10; i++) num.put(i, i);
for(i=9; i>=0; i--) cout << num.get(i);
cout << "\n";
// create another array and initialize with num
array x(num); // invokes copy constructor
for(i=0; i<10; i++) cout << x.get(i);
return 0;
}
Let's look closely at what happen s when num is used to initialize x in the statement
array x(num); // invokes copy constructor
The copy constructor is called, memory for the new array is allocated and stored in x.p,
and the contents of num are copied to x's array. In this way, x and num have arrays
that contain the same values, but each array is separate and distinct. (That is, num.p
and x.p do not point to the same piece of memory.) If the copy constructor had not
been created, the default bitwise initialization would have resulted in x and num
sharing the same memory for their arrays. (That is, num.p and x.p would have indeed
pointed to the same location.)
Remember that the copy constructor is called only for initializations. For example,
this sequence does not call the copy constructor defined in the preceding program:
array a(10);
// ...
array b(10);
b = a; // does not call copy constructor



Access in cpp classes

When a base class is inherited as private, all public and protected members of that class
become private members of the derived class. However, in certain circumstances, you
may want to restore one or more inherited members to their original access
specification. For example, you might want to grant certain public members of the base
class public status in the derived class even though the base class is inherited as private. 
 
In Standard C++, you have two ways to accomplish this. First, you can use a
using statement, which is the preferred way. The second way to restore an inherited 
member's access specification is to employ an access declaration
within the derived class. Access declarations are currently supported by Standard C++,
but they are deprecated. This means that they should not be used for new code. Since
there are still many, many existing programs that use access declarations, they will be
examined here.
An access declaration takes this general form:
base-class::member;
The access declaration is put under the appropriate access heading in the derived class'
declaration. Notice that no type declaration is required (or, indeed, allowed) in an
access declaration.
To see how an access declaration works, let's begin with this short fragment:
class base {
public:
int j; // public in base
};
// Inherit base as private.
class derived: private base {
public:
// here is access declaration
base::j; // make j public again
.
.
.
};
Because base is inherited as private by derived, the public member j is made a private
member of derived. However, by including
base::j;
as the access declaration under derived's public heading, j is restored to its public status.
You can use an access declaration to restore the access rights of public and
protected members. However, you cannot use an access declaration to raise or lower a
member's access status. For example, a member declared as private in a base class
cannot be made public by a derived class. (If C++ allowed this to occur, it would
destroy its encapsulation mechanism!)
The following program illustrates the access declaration; notice how it uses access
declarations to restore j, seti(), and geti() to public status.
#include
using namespace std;
class base {
int i; // private to base
public:
int j, k;
void seti(int x) { i = x; }
int geti() { return i; }
};
// Inherit base as private.
class derived: private base {
public:
/* The next three statements override
base's inheritance as private and restore j,
seti(), and geti() to public access. */
base::j; // make j public again - but not k
base::seti; // make seti() public
base::geti; // make geti() public
// base::i; // illegal, you cannot elevate access
int a; // public
};
int main()
{
derived ob;
//ob.i = 10; // illegal because i is private in derived
ob.j = 20; // legal because j is made public in derived
//ob.k = 30; // illegal because k is private in derived
ob.a = 40; // legal because a is public in derived
ob.seti(10);
cout << ob.geti() << " " << ob.j << " " << ob.a;
return 0;
}
Access declarations are supported in C++ to accommodate those situations in
which most of an inherited class is intended to be made private, but a few members are
to retain their public or protected status.
While Standard C++ still supports access declarations, they are deprecated. This
means that they are allowed for now, but they might not be supported in the future.
Instead, the standard suggests achieving the same effect by applying the using
keyword.

Wednesday, August 13, 2008

Escape characters and printf

Escape Sequence Character represented
\n newline
\t tab
\\ backslash itself
\' quote ``'''
\" double quote ``"''
For example,

printf("\t\"My name is \'%s\'\"\n", "Jim");
Which prints

"My name is 'Jim'"

I/O in c without printf and scanf.

Problem
I/O in c without printf and scanf.
Method 1 - getchar and putchar
int getchar();
int putchar(int value);

Sample Program
#include <stdio .h>
int main(void)
{
    int c;
    while ((c = getchar()) != EOF)
    {
        putchar(c);
    }
    return 0;
}

Note the use of parentheses. c=gethar()!=EOF implies whether c = 0 or 1 depending on whether character get is not EOF or is EOF. EOF is 257 , so use int rather than char.


Method 2 - gets and puts
gets(name of string) ;
int puts(name of string);
for puts - It terminates the line with a new line, '\n'. It will return EOF is an error occurred. It will return a positive number on success.
Sample code
char name[60];

if ((pt = gets(name)) == NULL)
{
    printf("Error on read\n");
    return(1);
}
puts(name);

Thanks

Printf with %

 Format Specifiers
cCharactera
d or iSigned decimal integer392
e EScientific notation (mantise/exponent) using e character3.9265e+2
3.9265E+2
fDecimal floating point392.65
gUse the shorter of %e or %f392.65
GUse the shorter of %E or %f392.65
oSigned octal610
sString of characterssample
uUnsigned decimal integer7235
xUnsigned hexadecimal integer7fa
XUnsigned hexadecimal integer (capital letters)7FA
pPointer addressB800:0000
nNothing printed. The argument must be a pointer to a signed int, where the number of characters written so far is stored.
%A % followed by another % character will write % to stdout.



Integer
 %d    print as decimal integer
 %6d    print as decimal integer, at least 6 characters wide
Float
 %f    print as floating point
 %6f    print as floating point, at least 6 characters wide
 %.2f    print as floating point, 2 characters after decimal point
 %6.2f     print as floating point, at least 6 wide and 2 after decimal point

flagsdescription
-Left-justify within the given field width; Right justification is the default (see width sub-specifier).
+Forces to preceed the result with a plus or minus sign (+ or -) even for positive numbers. By default, only negative numbers are preceded with a - sign.
(space)If no sign is going to be written, a blank space is inserted before the value.
#Used with o, x or X specifiers the value is preceeded with 0, 0x or 0X respectively for values different than zero.
Used with e, E and f, it forces the written output to contain a decimal point even if no digits would follow. By default, if no digits follow, no decimal point is written.
Used with g or G the result is the same as with e or E but trailing zeros are not removed.
0Left-pads the number with zeroes (0) instead of spaces, where padding is specified (see width sub-specifier).

widthdescription
(number)Minimum number of characters to be printed. If the value to be printed is shorter than this number, the result is padded with blank spaces. The value is not truncated even if the result is larger.
*The width is not specified in the format string, but as an additional integer value argument preceding the argument that has to be formatted.
.precisiondescription
.numberFor integer specifiers (d, i, o, u, x, X): precision specifies the minimum number of digits to be written. If the value to be written is shorter than this number, the result is padded with leading zeros. The value is not truncated even if the result is longer. A precision of 0 means that no character is written for the value 0.
For e, E and f specifiers: this is the number of digits to be printed after the decimal point.
For g and G specifiers: This is the maximum number of significant digits to be printed.
For s: this is the maximum number of characters to be printed. By default all characters are printed until the ending null character is encountered.
For c type: it has no effect.
When no precision is specified, the default is 1. If the period is specified without an explicit value for precision, 0 is assumed.
.*The precision is not specified in the format string, but as an additional integer value argument preceding the argument that has to be formatted.
lengthdescription
hThe argument is interpreted as a short int or unsigned short int (only applies to integer specifiers: i, d, o, u, x and X).
lThe argument is interpreted as a long int or unsigned long int for integer specifiers (i, d, o, u, x and X), and as a wide character or wide character string for specifiers c and s.
LThe argument is interpreted as a long double (only applies to floating point specifiers: e, E, f, g and G).
additional arguments
Depending on the format string, the function may expect a sequence of additional arguments, each containing one value to be inserted instead of each %-tag specified in the format parameter, if any. There should be the same number of these arguments as the number of %-tags that expect a value.

Return Value

On success, the total number of characters written is returned.
On failure, a negative number is returned.
Examples:
printf("%A", b);
             B                 output

c               'a'                 a
c                'A'               A
d       1977
ld      650000 
10d     1977      ^^^^^^1977 
010d    1977      0000001977
x       100       64     
o       100       144
#x      100       0x64
#o      100       064
4.2f    3.1416    3.14  
+.0e    3.1416    +3e+000
E       3.1416    3.141600E+000
*d      5,10      ^^^10
+ and -
printf("%5s", 'foo');  # prints '  foo'
printf("%-5s", 'foo');  # prints 'foo  ' 
 
' ' (a space): To specify that a blank should be left before a
positive number.
printf("% d", 7);  # prints ' 7'
printf("% d", -7);  # prints '-7'
Precision
printf("%.3d", 7);  # prints '007'
 
string :
printf("%.3s", 'foobar');          # prints 'foo'
printf("%.3s", 'foobar');   # prints 'foo'
printf("%.10s", 'foobar');   # prints 'foobar'
printf("%5.5s %5.5s", 'foobar', 'baz');  # prints 'fooba   baz'
 
printf("%.2f", 3.66666);          # prints '3.66' 
printf("%.2f", 9.333333);          # prints '9.34'
printf("%.2f", 9);           # prints '9.00'
printf("%.3f", 7);           # prints 007
Miscellaneous
The character 'V' will interpret an integer as Perl's standard integer
type.
printf("%Vd", 7);  # prints '7'
 

Friday, August 8, 2008

C preprocessor

The C preprocessor (cpp) is the preprocessor for the C programming language. In many C implementations, it is a separate program invoked by the compiler as the first part of translation. The preprocessor handles directives for source file inclusion (#include), macro definitions (#define), and conditional inclusion (#if). The language of preprocessor directives is not strictly specific to the grammar of C, so the C preprocessor can also be used independently to process other types of files.
The transformations it makes on its input form the first four of C's so-called Phases of Translation. Though an implementation may choose to perform some or all phases simultaneously, it must behave as if it performed them one-by-one in order.

Contents

  • 1 Phases
  • 2 Including files
  • 3 Conditional compilation
  • 4 Macro definition and expansion

    • 4.1 Precedence
    • 4.2 Multiple lines
    • 4.3 Multiple evaluation of side effects
    • 4.4 Token concatenation
    • 4.5 Semicolons

      • 4.5.1 Multiple statements
    • 4.6 Quoting macro arguments


      • 4.6.1 Indirectly quoting macro arguments
    • 4.7 Variadic macros
  • 5 X-Macros
  • 6 User-defined compilation errors and warnings
  • 7 Compiler-specific preprocessor features
  • 8 Standard positioning macros
  • 9 Compiler-specific predefined macros
  • 10 As a general-purpose preprocessor
  • 11 See also


Including files

The most common use of the preprocessor is to include another file:
#include  
int main (void)
{
    printf("Hello, world!\n");
    return 0;
}
The preprocessor replaces the line #include with the system header file of that name, which declares the printf() function amongst other things. More precisely, the entire text of the file 'stdio.h' replaces the #include directive.
This can also be written using double quotes, e.g. #include "stdio.h". If the filename is enclosed within angle brackets, the file is searched for in the standard compiler include paths. If the filename is enclosed within double quotes, the search path is expanded to include the current source directory. C compilers and programming environments all have a facility which allows the programmer to define where include files can be found. This can be introduced through a command line flag, which can be parameterized using a makefile, so that a different set of include files can be swapped in for different operating systems, for instance.
By convention, include files are given a .h extension, and files not included by others are given a .c extension. However, there is no requirement that this be observed. Occasionally you will see files with other extensions included, in particular files with a .def extension may denote files designed to be included multiple times, each time expanding the same repetitive content.
#include often compels the use of #include guards or #pragma once to prevent double inclusion.

Conditional compilation

The #if, #ifdef, #ifndef, #else, #elif and #endif directives can be used for conditional compilation.
#define __WINDOWS__
 
#ifdef __WINDOWS__
#include 
#else
#include 
#endif
#if VERBOSE >=2
  print("trace message");
#endif
The first line defines a macro __WINDOWS__. The macro could be defined implicitly by the compiler, or specified on the compiler's command line, perhaps to control compilation of the program from a makefile.
The subsequent code tests if a macro __WINDOWS__ is defined. If it is, as in this example, the file is included, otherwise .

Macro definition and expansion

There are two types of macros, object-like and function-like. Object-like macros do not take parameters; function-like macros do. The generic syntax for declaring an identifier as a macro of each type is, respectively,
#define  
#define () 
Note that the function-like macro declaration must not have any whitespace between the identifier and the first, opening, parentheses.
Wherever the identifier appears in the source code it is replaced with the replacement token list, which can be empty. For an identifier declared to be a function-like macro, it is only replaced when the following token is also a left parentheses that begins the argument list of the macro invocation. The exact procedure followed for expansion of function-like macros with arguments is subtle.
Object-like macros were conventionally used as part of good programming practice to create symbolic names for constants, e.g.
#define PI 3.14159
instead of hard-coding those numbers throughout one's code. However, C++ and newer versions of C provide the const directive, which is often better because it behaves more like a variable (except that its value can never change).
An example of a function-like macro is:
#define RADTODEG(x) ((x) * 57.29578)
This defines a radians to degrees conversion which can be written subsequently, e.g. RADTODEG(34) or RADTODEG (34). This is expanded in-place, so the caller does not need to litter copies of the multiplication constant all over his code. The macro here is written as all uppercase to emphasize that it is a macro, not a compiled function.

Precedence

Note that the example macro RADTODEG(x) given above uses normally superfluous parentheses both around the argument and around the entire expression. Omitting either of these can lead to unexpected results. For example:
  • Macro defined as
#define RADTODEG(x) (x * 57.29578)
will expand
RADTODEG(a + b)
to
(a + b * 57.29578)
  • Macro defined as
#define RADTODEG(x) (x) * 57.29578
will expand
1 / RADTODEG(a)
to
1 / (a) * 57.29578
neither of which give the intended result.

Multiple lines

A macro can be extended over as many lines as required using a backslash escape character at the end of each line. The macro ends after the first line which does not end in a backslash.
The extent to which multi-line macros enhance or reduce the size and complexity of the source of a C program, or its readability and maintainability is open to debate (there is no experimental evidence on this issue).

Multiple evaluation of side effects

Another example of a function-like macro is:
#define MIN(a,b) ((a)>(b)?(b):(a))
Notice the use of the ?: operator. This illustrates one of the dangers of using function-like macros. One of the arguments, a or b, will be evaluated twice when this "function" is called. So, if the expression MIN(++firstnum,secondnum) is evaluated, then firstnum may be incremented twice, not once as would be expected.
A safer way to achieve the same would be to use a typeof-construct:
#define max(a,b) \
       ({ typeof (a) _a = (a); \
           typeof (b) _b = (b); \
         _a > _b ? _a : _b; })
This will cause the arguments to be evaluated only once, and it will not be type-specific anymore. This construct is not legal ANSI C; both the typeof keyword, and the construct of placing a compound statement within parentheses, are non-standard extensions implemented in the popular GNU C compiler (GCC). If you are using GCC, the same general problem can also be solved using a static inline function, which is as efficient as a #define. The inline function allows the compiler to check/coerce parameter types -- in this particular example this appears to be a disadvantage, since the 'max' function as shown works equally well with different parameter types, but in general having the type coercion is often an advantage.
Within ANSI C, there is no reliable general solution to the issue of side-effects in macro arguments.

Token concatenation

Token concatenation, also called token pasting, is one of the most subtle — and easy to abuse — features of the C macro preprocessor. Two arguments can be 'glued' together using ## preprocessor operator; this allows two tokens to be concatenated in the preprocessed code. This can be used to construct elaborate macros which act much like C++ templates (without many of their benefits).
For instance:
#define MYCASE(item,id) \
case id: \
  item##_##id = id;\
break
 
switch(x) {
    MYCASE(widget,23);
}
The line MYCASE(widget,23); gets expanded here into
case 23: 
  widget_23 = 23; 
break;
(The semicolon following the invocation of MYCASE becomes the semicolon that completes the break statement.)

Semicolons

One stylistic note about the above macro is that the semicolon on the last line of the macro definition is omitted so that the macro looks 'natural' when written. It could be included in the macro definition, but then there would be lines in the code without semicolons at the end which would throw off the casual reader. Worse, the user could be tempted to include semicolons anyway; in most cases this would be harmless (an extra semicolon denotes an empty statement) but it would cause errors in control flow blocks:
#define PRETTY_PRINT(s) \
   printf ("Message: \"%s\"\n", s);
 
  if (n < 10)
    PRETTY_PRINT("n is less than 10");
  else
    PRETTY_PRINT("n is at least 10");
This expands to give two statements – the intended printf and an empty statement – in each branch of the if/else construct, which will cause the compiler to give an error message similar to:
error: expected expression before ‘else’
gcc 4.1.1

Multiple statements

Inconsistent use of multiple-statement macros can result in unintended behaviour. The code
#define CMDS \
   a = b; \
   c = d
 
  if (var == 13)
    CMDS;
  else
    return;
will expand to
if (var == 13)
    a = b;
  c = d;
  else
    return;
which is a syntax error (the else is lacking a matching if).
The macro can be made safe by replacing the internal semicolon with the comma operator, since two operands connected by a comma form a single statement. The comma operator is the lowest precedence operator. In particular, its precedence is lower than the assignment operator's, so that a = b, c = d does not parse as a = (b,c) = d. Therefore,
#define CMDS a = b, c = d
 
  if (var == 13)
    CMDS;
  else
    return;
will expand to
if (var == 13)
    a = b, c = d;
  else
    return;
The problem can also be fixed without using the comma operator:
#define CMDS \
  do { \
    a = b; \
    c = d; \
  } while (0)
expands to
if (var == 13)
    do {
      a = b;
      c = d;
    } while (0);
  else
    return;
The do and while (0) are needed to allow the macro invocation to be followed by a semicolon; if they were omitted the resulting expansion would be
if (var == 13) {
      a = b;
      c = d;
  }
  ;
  else
    return;
The semicolon in the macro's invocation above becomes an empty statement, causing a syntax error at the else by preventing it matching up with the preceding if.

Quoting macro arguments

Although macro expansion does not occur within a quoted string, the text of the macro arguments can be quoted and treated as a string literal by using the "#" directive(also known as the "Stringizing Operator"). For example, with the macro
#define QUOTEME(x) #x
the code
printf("%s\n", QUOTEME(1+2));
will expand to
printf("%s\n", "1+2");
This capability can be used with automatic string literal concatenation to make debugging macros. For example, the macro in
#define dumpme(x, fmt) printf("%s:%u: %s=" fmt, __FILE__, __LINE__, #x, x)
 
int some_function() {
    int foo;
    /* [a lot of complicated code goes here] */
    dumpme(foo, "%d");
    /* [more complicated code goes here] */
}
would print the name of an expression and its value, along with the file name and the line number.

Indirectly quoting macro arguments

The "#" directive can also be used indirectly. For example, with the macro:
#define FOO bar
#define _QUOTEME(x) #x
#define QUOTEME(x) _QUOTEME(x)
the code
printf("FOO=%s\n", QUOTEME(FOO));
will expand to
printf("FOO=%s\n", "bar");

Variadic macros

Main article: Variadic macro
Macros that can take a varying number of arguments (variadic macros) are not allowed in C89, but were introduced by a number of compilers and standardised in C99. Variadic macros are particularly useful when writing wrappers to variable parameter number functions, such as printf, for example when logging warnings and errors.

X-Macros

One little-known usage-pattern of the C preprocessor is known as "X-Macros". An X-Macro is an #include file (commonly using a ".def" extension instead of the traditional ".h") that contains a list of similar macro calls (which can be referred to as "component macros"). The include file is then referenced repeatedly in the following pattern:
(Given that the include file is "xmacro.def" and it contains a list of component macros of the style "foo(x, y, z)")
#define foo(x, y, z) doSomethingWith(x, y, z);
#include "xmacro.def"
#undef foo
 
#define foo(x, y, z) doSomethingElseWith(x, y, z);
#include "xmacro.def"
#undef foo
 
(etc...)
The most common usage of X-Macros is to establish a list of C objects and then automatically generate code for each of them.
Common sets of objects are a set of global configuration settings, a set of members of a structure, a list of possible XML tags for converting an XML file to a quickly traversable tree or the body of an enum declaration, although other lists are possible.
Once the X-Macro has been processed to create the list of objects, the component macros can be redefined to generate, for instance, accessor and/or mutator functions. Structure serializing and deserializing are also commonly done.
Here is an example of an X-Macro that establishes a struct and automatically creates serialize/deserialize functions:
(Note: for simplicity, we don't account for endianness or buffer overflows)
File:  object.def
 
struct_member( x, int );
struct_member( y, int );
struct_member( z, int );
struct_member( radius, double );
 
 
File: star_table.c
 
typedef struct
{
#define struct_member( name, type ) type name;
#include "object.def"
#undef struct_member
} star;
 
void serialize_star( const star *_star, unsigned char *buffer )
 
{
/* Copy each member's data into buffer and move the pointer. */
#define struct_member( name, type ) memcpy(buffer, (unsigned char *) &(_star->name), sizeof(_star->name) ); buffer += sizeof(_star->name);
#include "object.def"
#undef struct_member
}
 
void deserialize_star( star *_star, const unsigned char *buffer )
 
{
/* Copy each member's data out of buffer and move the pointer. */
#define struct_member( name, type ) memcpy((unsigned char *) &(_star->name), buffer, sizeof(_star->name) ); buffer += sizeof(_star->name);
#include "object.def"
#undef struct_member
}
Often, handlers for individual data types are created and accessed using the token concatenation ("##") and quoting ("#") operators. For instance, the following might be added to the above code:
void print_int( int val )
{
   printf( "%d", val )
}
 
void print_double( double val )
{
   printf( "%g", val )
}
 
void print_star( const star *_star )
 
{
/* print_##type will be replaced with print_int or print_double */
#define struct_member( name, type ) printf( "%s: ", #name ); print_##type( _star->name ); printf("\n");
#include "object.def"
#undef struct_member
}
The creation of a separate header file can be avoided by creating a single macro containing what would be the contents of the file. For instance, the above defined "object.def" could be replaced with this macro:
#define object_def \
struct_member( x, int ); \
struct_member( y, int ); \
struct_member( z, int ); \
struct_member( radius, double );
and then all calls to '#include "object.def"' could be replaced with a simple object_def statement. The above function would become:
void print_star( const star *_star )
 
{
/* print_##type will be replaced with print_int or print_double */
#define struct_member( name, type ) printf( "%s: ", #name ); print_##type( _star->name ); printf("\n");
object_def
#undef struct_member
}
This approach can be dangerous in that the entire macro set is always interpreted as if it was on a single source line, which could encounter compiler limits with complex component macros and/or long member lists.

User-defined compilation errors and warnings

The #error directive inserts an error message into the compiler output.
#error "Gaah!"
This prints "Gaah!" in the compiler output and halts the computation at that point. This is extremely useful for determining whether a given line is being compiled or not. It is also useful if you have a heavily parameterized body of code and want to make sure a particular #define has been introduced from the makefile, e.g.:
#ifdef WINDOWS
    ... /* Windows specific code */
#elif defined(UNIX)
    ... /* Unix specific code */
#else
    #error "What's your operating system?"
#endif
Some implementations provide a non-standard #warning directive to print out a warning message in the compiler output, but not stop the compilation process. A typical use is to warn about the usage of some old code, which is now unfavored and only included for compatibility reasons, e.g.:
#warning "Do not use ABC, which is deprecated. Use XYZ instead."
Although the text following the #error or #warning directive does not have to be quoted, it is good practice to do so. Otherwise, there may be problems with apostrophes and other characters that the preprocessor tries to interpret. Microsoft C uses #pragma message ( "text" ) instead of #warning.

Compiler-specific preprocessor features

The #pragma directive is a compiler specific directive which compiler vendors may use for their own purposes. For instance, a #pragma is often used to allow suppression of specific error messages, manage heap and stack debugging, etc.
C99 introduced a few standard #pragma directives, taking the form #pragma STDC …, which are used to control the floating-point implementation.

Standard positioning macros

Certain symbols are predefined in ANSI C. Two useful ones are __FILE__ and __LINE__, which expand into the current file and line number. For instance:
// debugging macros so we can pin down message provenance at a glance
#define WHERESTR "[file %s, line %d] "
#define WHEREARG __FILE__,__LINE__
 
printf(WHERESTR ": hey, x=%d\n", WHEREARG, x);
This prints the value of x, preceded by the file and line number, allowing quick access to which line the message was produced on. Note that the WHERESTR argument is concatenated with the string following it.

Compiler-specific predefined macros

Compiler-specific predefined macros are usually listed in the compiler documentation, although this is often incomplete. The Pre-defined C/C++ Compiler Macros project lists "various pre-defined compiler macros that can be used to identify standards, compilers, operating systems, hardware architectures, and even basic run-time libraries at compile-time".
Some compilers can be made to dump at least some of their useful predefined macros, for example:
GNU C Compiler
gcc -dM -E - < /dev/null
HP-UX ansi C compiler
cc -v fred.c (where fred.c is a simple test file)
SCO OpenServer C compiler
cc -## fred.c (where fred.c is a simple test file)
Sun Studio C/C++ compiler
cc -## fred.c (where fred.c is a simple test file)

As a general-purpose preprocessor

Since the C preprocessor can be invoked independently to process files other than those containing to-be-compiled source code, it can also be used as a "general purpose preprocessor" for other types of text processing. One particularly notable example is the now-deprecated imake system; more examples are listed at General purpose preprocessor.