Post your tips for making life easier in C and C++. I'll start:


Standard vector object initialization

The biggest problem with the standard vector class is that one can't use an array initializer. This forces us to do something like this:

#include <iostream>
#include <vector>

using namespace std;

int main()
{
  vector<int> v;

  v.push_back(1);
  v.push_back(2);
  v.push_back(3);
  v.push_back(4);
  v.push_back(5);

  // Use the vector
}

Anyone who's had the rule of redundancy pounded into their head knows that the previous code could be wrapped in a loop:

#include <iostream>
#include <vector>

using namespace std;

int main()
{
  vector<int> v;

  for (int i = 1; i < 6; i++)
    v.push_back(i);

  // Use the vector
}

However, it's not terribly elegant, especially for a vector of complex types. So, Narue's first timesaving tip for C++ is to use a temporary array so that you can make use of an initializer. Because the vector class defines a constructor that takes a range of iterators, you can use the array to initialize your vector:

#include <iostream>
#include <vector>

using namespace std;

int main()
{
  int a[] = {1,2,3,4,5};
  vector<int> v(a, a + 5);

  // Use the vector
}
Duki commented: goodpost. my prof used it in class +4
Sturm commented: Pretty cool, never knew that. +2

One of my favorite discoveries in C++ regards displaying such a list.

Initially one might do this.

#include <iostream>
#include <vector>

using namespace std;

int main()
{
  int a[] = {1,2,3,4,5};
  vector<int> v(a, a + 5);

  for (int i = 0; i < 5; ++i)
  {
     cout << v[i] << endl;
  }
}

Or perhaps even this.

#include <iostream>
#include <vector>
#include <iterator>

using namespace std;

int main()
{
  int a[] = {1,2,3,4,5};
  vector<int> v(a, a + 5);

  vector<int>::const_iterator it, end = v.end();
  for (it = v.begin(); it != end; ++it)
  {
     cout << *it << endl;
  }
}

But I happend upon the following that can make things even easier.

#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>

using namespace std;

int main()
{
  int a[] = {1,2,3,4,5};
  vector<int> v(a, a + 5);

  copy(v.begin(), v.end(), ostream_iterator<int>(cout, "\n"));
}

The output for all of these is merely this.

1
2
3
4
5

From the code snippet on the very same subject is another way to initialize a vector ...

// another way to load a vector ...
  vector<char> cV(50, '-');
  cout << "this vector has 50 char - :\n";
  for(k = 0; k < cV.size(); k++)
  { 
    cout << cV[k];
  } 
  cout << endl;

How to remove duplicate elements from a vector ...

// load a vector with an integer array and remove duplicates
...
  int b[] = {0, 1, 2, 3, 4, 3, 4, 5, 6, 4};
  // load using (array, array + NumberOfElements)
  vector<int> iV4(b, b + sizeof(b)/sizeof(int));

  // remove the duplicates with sort(), erase() and unique()
  cout << "removed the duplicate elements:\n";
  sort( iV4.begin(), iV4.end() );
  iV4.erase( unique( iV4.begin(), iV4.end() ), iV4.end() );
  // show the result
  for(k = 0; k < iV4.size(); k++)
  { 
    cout << setw(8) << iV4[k]; 
  }
  cout << endl;
...

Removing a newline in C

The fgets function in C is annoying in that it copies a newline character to the buffer:

#include <stdio.h>

int main ( void )
{
  char buffer[BUFSIZ];

  printf ( "Enter a string: " );
  if ( fgets ( buffer, sizeof buffer, stdin ) != NULL )
    printf ( "|%s|\n", buffer );

  return 0;
}

When you run this program and type "test", this is the output:

|test
|

This is a good feature for dealing with long lines and such, but for the most part it serves only to frustrate beginners. Experienced programmers have learned to remove the newline with tricks such as:

#include <stdio.h>
#include <string.h>

int main ( void )
{
  char buffer[BUFSIZ];

  printf ( "Enter a string: " );
  if ( fgets ( buffer, sizeof buffer, stdin ) != NULL ) {
    size_t len = strlen ( buffer );

    if ( buffer[len - 1] == '\n' )
      buffer[len - 1] = '\0';

    printf ( "|%s|\n", buffer );
  }

  return 0;
}

Or more commonly:

#include <stdio.h>
#include <string.h>

int main ( void )
{
  char buffer[BUFSIZ];

  printf ( "Enter a string: " );
  if ( fgets ( buffer, sizeof buffer, stdin ) != NULL ) {
    char *newline = strchr ( buffer, '\n' );

    if ( newline != NULL )
      *newline = '\0';

    printf ( "|%s|\n", buffer );
  }

  return 0;
}

The annoying part of this issue is that one often is required to declare a variable, test for a newline character explicitly, and replace it explicitly. A quick timesaver when writing code is the strcspn function:

#include <stdio.h>
#include <string.h>

int main ( void )
{
  char buffer[BUFSIZ];

  printf ( "Enter a string: " );
  if ( fgets ( buffer, sizeof buffer, stdin ) != NULL ) {
    buffer[strcspn ( buffer, "\n" )] = '\0';
    printf ( "|%s|\n", buffer );
  }

  return 0;
}

The downside to this timesaver is that it doesn't save time during execution. The strcspn trick will usually be slower than most other methods of removing a newline. However, because the performance hit of input far outweighs any difference in speed for removing the newline character.

Removing a newline in C

The fgets function in C is annoying in that it copies a newline character to the buffer:

instead of performing that little dance every time, i'd just write a new function and get it over with.

char *fget(char *s, int size, FILE * stream)
{
        char *ptr;
        int c;

        for (ptr = s; size > 1; --size) {
                c = getc(stream);
                if (c == EOF || c == '\n')
                        break;
                *ptr++ = c;
        }

        if (ptr == s) {
                ptr = NULL;
        } else {
                *ptr = 0;
        }

        return ptr;
}

>i'd just write a new function and get it over with
That's one way to go about it, but since fgets is already there and is presumably written with performance in mind, it's smarter to make use of it:

char *reads ( char *s, size_t limit, FILE *stream )
{
  if ( fgets ( s, limit, stream ) == NULL ) {
    return NULL;
  } else {
    char *newline = strchr ( s, '\n' );

    if ( newline != NULL )
      *newline = '\0';

    return s;
  }
}

It's also easier to verify correctness when you use the standard library instead of trying to rewrite it.

>i'd just write a new function and get it over with
That's one way to go about it, but since fgets is already there and is presumably written with performance in mind,

Presumably. But, having implemented the C89 stdlib in it's entirety I can assure you that the last thing it's designers had in mind when devising the stdio library was performance. If you require fast I/O, you'd do well to look elsewhere.

it's smarter to make use of it:
...
It's also easier to verify correctness when you use the standard library instead of trying to rewrite it.

It's easier to verify correctness when your functions have a single exit point (hint) ;)
speaking of weird code, my function should return s and not ptr.

>It's easier to verify correctness when your functions have a single exit point (hint)
That's debatable. Often it's harder in my experience because you have to bend over backward with unnecessary constructs to ensure a single exit point. For trivial functions such as the ones we posted, it's hardly brain surgery to verify correctness. For non-trivial functions, it's difficult to maintain simplicty and still adhere to structured programming "good practice". I prefer to err on the side of simplicity and transparency.

>had in mind when devising the stdio library was performance.
Performance was a primary concern for the design of C and its libraries. As another programmer who's implemented the C89 library in its entirety, I'm not entirely sure what you're referring to. Let me know in PM so we don't end up going too far off topic.

>speaking of weird code, my function should return s and not ptr
Oh good, I thought maybe my mentioning correctness was too subtle of a hint. ;)

Seeing as this thread is about timesaving what about inheritance? Its a good time saver especially for the masses intent on game creation.

Say you make a class such as

class CBASE_ENTITY
{
// code here. this class would provide functions for 'things' that exist in the game
};

if you wanted to specialise and create objects such as moving platforms / players / weapon models ect you can simply

class CBASE_PLAYER : pubic CBASE_ENTITY { 
// player specific code.
};

Without re-coding the entire class. Quite a few people forget inheritance and end up making some really messy classes! Dont forget that pointers are interchangable between derived and base classes which is VERY VERY useful....

An example of this timesaving would be to create a model cass, inherit a weapon class off it, and inherit weapons off the weapon base class. Then also pointers can be moved around the weapons derived classes.... im sure you can work out where this is going! If you look at the Half-Life source they make extensive use of inheritance to make a class oreentated (spelling) source which works very well....

Finding Array Size

Starting Out
When first starting out, we might write some code that initializes an array, perhaps does some manipulation, and then displays the results. It might look something like this (contrived example):

void foo(void)
{
   int array[10];
   int i;
   /* Initialize array. */
   for ( i = 0; i < 10; ++i )
   {
      array[i] = i;
   }
   /* Perform calculations. */
   for ( i = 0; i < 10; ++i )
   {
      array[i] *= 2;
   }
   /* Print array. */
   for ( i = 0; i < 10; ++i )
   {
      printf("%d,", array[i]);
   }
   putchar('\n');
}

We notice that if we want to change the array dimension, there are several lines of code to edit to make the change. Maintaining code like this is more difficult because in larger sets of code, finding all of the places that need to be changed becomes less trivial.

Using a Symbolic Constant
To avoid this, it is often recommended to use a symbolic constant instead.

#define SIZE 10

void bar(void)
{
   int array[SIZE];
   int i;
   /* Initialize array. */
   for ( i = 0; i < SIZE; ++i )
   {
      array[i] = i;
   }
   /* Perform calculations. */
   for ( i = 0; i < SIZE; ++i )
   {
      array[i] *= 2;
   }
   /* Print array. */
   for ( i = 0; i < SIZE; ++i )
   {
      printf("%d,", array[i]);
   }
   putchar('\n');
}

Now we can see we only need to change the #define to make a change to the array size. Unfortunately, purveyors of this wisdom often stop there.

The debugging hazard that this leads to often materializes itself in some header that is used to declare dozens of such constants. Some may like this, but I've found this to be a maintenance headache as well. For example, let's take a look at this code fragment.

for ( i = 0; i < ASIZE; ++i )
   {
      printf("%d,", array[i]);
   }

Is it correct? You can't tell from this alone. You have to find the declaration of the array and double check. That alone is probably not that big of a deal, except when you have data that may be declared far away from this section of code.

Another Way
A cure is such an old piece of code, it's hard to imagine more people aren't aware of it long before they've learned a struct. It works by dividing the total size of the array (in bytes) by the size of the first element of the array (in bytes); this gives the number of elements. This is calculated at compile time.

void baz(void)
{
   int array[10];
   size_t i;
   /* Initialize array. */
   for ( i = 0; i < sizeof array / sizeof *array; ++i )
   {
      array[i] = i;
   }
   /* Perform calculations. */
   for ( i = 0; i < sizeof array / sizeof *array; ++i )
   {
      array[i] *= 2;
   }
   /* Print array. */
   for ( i = 0; i < sizeof array / sizeof *array; ++i )
   {
      printf("%d,", array[i]);
   }
   putchar('\n');
}

Now if you want to change the size of the array, you do it in only one place, and that place happens to be right where you define the array. If we saw the following fragment, is it correct?

for ( i = 0; i < sizeof array / sizeof *array; ++i )
   {
      printf("%d,", array[i]);
   }

If array is an array in scope, yes.

Further Considerations
Some programmers may prefer to use a macro to make it easier to read; either of these are examples.

#define ARRAYSIZE(x)  (sizeof(x)/sizeof(*(x)))
#define NELEM(x)      (sizeof(x)/sizeof(x[0]))

So another way to write this is as follows.

void qux(void)
{
   int array[10];
   size_t i;
   /* Initialize array. */
   for ( i = 0; i < ARRAYSIZE(array); ++i )
   {
      array[i] = i;
   }
   /* Perform calculations. */
   for ( i = 0; i < NELEM(array); ++i )
   {
      array[i] *= 2;
   }
   /* Print array. */
   for ( i = 0; i < ARRAYSIZE(array); ++i )
   {
      printf("%d,", array[i]);
   }
   putchar('\n');
}

Use With Functions
Finally, if you pass "the array" to a function, you are really only passing a pointer to the first element of the array. In such cases, you should also pass a size parameter to the function.

void fum(int *array, size_t size)
{
   size_t i;
   /* Initialize array. */
   for ( i = 0; i < size; ++i )
   {
      array[i] = i;
   }
   /* Perform calculations. */
   for ( i = 0; i < size; ++i )
   {
      array[i] *= 2;
   }
   /* Print array. */
   for ( i = 0; i < size; ++i )
   {
      printf("%d,", array[i]);
   }
   putchar('\n');
}

int main(void)
{
   int myarray[25];
   foo();
   bar();
   baz();
   qux();
   fum(myarray, ARRAYSIZE(myarray));
   return 0;
}

This one is entertaining, and useful too. We all know ("we" being C++ programmers who came from C or still use C extensively) that scanf will eat up a format nice and pretty:

scanf ( "%d-%d-%d", &m, &d, &y );

If the input stream does not contain an integer followed by a '-' followed by an integer (shush Dave, and humor me), followed by a '-' followed by an integer, the call will fail. Sadly, this useful feature isn't available in C++ unless you use scanf. Using iostreams, you would be forced to do something painful like this (with suitable error handling, of course):

cin>> m;
if ( cin.peek() == '-' )
  cin.ignore();
cin>> d;
if ( cin.peek() == '-' )
  cin.ignore();
cin>> y;

Wouldn't it be nice if we could just do this and be done with it?

cin>> m >>"-">> d >>"-">> y;

Well, unfortunately it's not quite that easy. One could overload operator>> for a pointer to const char, but that kind of invades the implementation's personal space and therefore, is not portable.

To do it would be trivial though:

istream& operator>> ( istream& in, const char *s )
{
  while ( *s != '\0' && in && in.peek() == *s ) {
    in.get();
    ++s;
  }

  if ( *s != '\0' )
    in.setstate ( ios::failbit );

  return in;
}

This was my solution (more or less). I didn't need something portable, and the benefit of clarity was a decisive factor. Looking toward portability though, just as a mental exercise, I also considered the manipulator approach:

class scan {
public:
  scan ( const char *init ): fmt ( init ) {}
  friend istream& operator>> ( istream& in, const scan& s )
  {
    while ( *s.fmt != '\0' && in && in.peek() == *s.fmt ) {
      in.get();
      ++s.fmt;
    }

    if ( *s.fmt != '\0' )
      in.setstate ( ios::failbit );

    return in;
  }
private:
  mutable const char *fmt;
};

It's almost as simple, but using it requires a bit more work:

cin>> m >> scan ( "-" ) >> d >> scan ( "-" ) >> y;

On a similar note, I also found a similar manipulator useful. The following manipulator will discard all characters in the stream up to (and including) a user defined character delimiter:

class moveto {
public:
  moveto ( istream::int_type init ): ch ( init ) {}
  friend istream& operator>> ( istream& in, const moveto& d )
  {
    if ( in.rdbuf()->in_avail() > 0 )
      in.ignore ( numeric_limits<streamsize>::max(), d.ch );

    return in;
  }
private:
  istream::int_type ch;
};

This is slightly more complicated than the usual "empty the buffer" call to ignore, designed to flush the stream of interactive input. That job could be performed with a simple moveto request:

cin>> moveto ( '\n' );

But, moveto is useful in parsing as well. :)

One can easily imagine how useful these manipulators can be. Not only does the scanf behavior of eating a format work with standard input and output, a clever programmer could easily pair them with stringstreams, fstreams, or even custom streams to solve a whole slew of formatted parsing problems without hacking together something big and ugly.

And with a little bit of extra work, the scan manipulator can be extended to more accurately mimic scanf's format processing.

I know this may not seem like a super time saving technique, but the way you name your variables will help save time and reduce compile time errors.. Having a conventional variable naming format will help keep things organized and easy to read.

Styles

Typically, most variable names get the every other word capitalized. Functions get the first letter of each word capitalized and constants get all of the letters capitalized.

Example:

Variable: First letter of every other word capitalized.

  • char theName[20];

Functions: First letter of each word capitalized .

  • void GetTheName();

Constants: All capitals

  • #define THENAME 20

Of course, sometimes choosing a good variable name can take a long time!

Reading an Integer

This is in many FAQs elsewhere, so this is just my repackaging of it here.

C Version

[B]#include[/B] <stdio.h>
[B]#include[/B] <stdlib.h>

[B]int[/B] [B]main[/B]([B]void[/B])
{
   [B]char[/B] response[32];
   /*
    * Prompt for input.
    */
   [B]fputs[/B] ( "Enter your number: ", stdout );
   [B]fflush[/B] ( stdout );
   /*
    * Read user response.
    */
   [B]if[/B] ( [B]fgets[/B] ( response, [B]sizeof[/B] response, stdin ) != NULL )
   {
      /*
       * Attempt to convert user's response into an integer using strtol. The
       * second parameter to strtol allows for greater error checking if used.
       */
      [B]int[/B] value = [B]strtol[/B] ( response, NULL, 10/* radix or base */ );
      /*
       * No error checking was done, but attempt to display integer value.
       */
      [B]printf[/B] ( "value = %d\n", value );
   }
   [B]return[/B] 0;
}

/* my output
Enter your number: 12345
value = 12345
*/

C++ Version

[B]#include[/B] <iostream>
[B]#include[/B] <string>
[B]#include[/B] <sstream>

[B]int[/B] [B]main[/B]([B]void[/B])
{
   std::string response;
   /*
    * Prompt for input.
    */
   std::[B]cout[/B] << "Enter your number: ";
   /*
    * Read user response.
    */
   std::[B]cin[/B] >> response;
   /*
    * Attempt to convert user's response into an integer using a stringstream.
    */
   std::istringstream convert(response);
   [B]int[/B] value;
   [B]if[/B] ( convert >> value )
   {
      std::[B]cout[/B] << "value = " << value << std::[B]endl[/B];
   }
   [B]return[/B] 0;
}

/* my output
Enter your number: 456879
value = 456879
*/

Koenig Lookup

There are three ways to use a name nested in a namespace. Making the namespace open to the current scope with a using directive:

using namespace std;

cout << "Hello world!" << endl;

Making only select names open to the current scope with a using declaration:

// Make cout and endl available, but nothing else
using std::cout;
using std::endl;

cout << "Hello world!" << endl;

And explicit qualification of every name for every use:

std::cout << "Hello world!" << std::endl;

It's best to never use the using directive unless you know for a fact that you won't have name clashes. That's usually not easily possible, and most people will suggest that you use explicit qualification all the time. The problem with that is explicit qualification is so verbose! Koenig lookup is a trick to shorten some of those names.

Here's a common example:

vector<int> c;

// ...

std::copy(c.begin(), c.end(), std::ostream_iterator<int>(std::cout, "\n"));

Koenig lookup says that if a function in a namespace takes an argument from the same namespace, the function need not be qualified because the compiler will look in that namespace for matching functions. So the following is legal C++:

copy(c.begin(), c.end(), std::ostream_iterator<int>(std::cout, "\n"));

copy takes an ostream_iterator object as an argument. Because both ostream_iterator and copy are members of namespace std, Koenig lookup finds copy via ostream_iterator. A third of the namespace qualification has been removed from this line, and that is a big timesaver when it all adds up. :)

commented: Very friendly, Ace in C++ in my eyes, doesn't have a problem in explaining something what you didn't understand the first time! +1

suppose you guys are writing a program which uses a number of loops,
use a single variable for all the loop counters and declare the variable to be of register storage class. what happens is that the variable gets stored in the cpu registers and the loops get executed a lot faster.
the syntax is:
register int i;
hope this was helpful.

declare the variable to be of register storage class. what happens is that the variable gets stored in the cpu registers and the loops get executed a lot faster.

Rather ancient advice. Better advice is to improve the algorithm rather than micro-optimize.
http://www.eskimo.com/~scs/cclass/krnotes/sx7g.html

Avoid Loop Control Using eof()

All over the 'net C++ programmers are taught to "read until end of file". This leads to the following (incorrect) idiom for loop control.

#include <iostream>
#include <fstream>

int main()
{
  std::ifstream file("file.txt");
  if ( file )
  {
     int i;
     while ( !file.eof() ) // bad!!
     {
        file >> i;
        std::cout << i << ' ';
     }
     std::cout << std:: endl;
  }
  return 0;
}

Run the above code with the following text file, "file.txt".

1 2 3 4 5 6 7 8 9 10

Your output will be like this.

1 2 3 4 5 6 7 8 9 10 10

Note the repeated 10.

What To Use Instead

Change your thinking to "while successfully reading input from a file" and know that the state of the stream -- indicating successful input or a failure -- is available from the input operation.

#include <iostream>
#include <fstream>

int main()
{
  std::ifstream file("file.txt");
  if ( file )
  {
     int i;
     while ( file >> i )
     {
        std::cout << i << ' ';
     }
     std::cout << std:: endl;
  }
  return 0;
}

The output is now correct.

1 2 3 4 5 6 7 8 9 10

Then, for amusement, change "file.txt" to this.

1 2 3 4 5 6 7 8 9 1A

Then run each of the above programs.

Another Example

A similar thing can be done when reading text.

#include <iostream>
#include <fstream>

int main()
{
  std::ifstream file("file.txt");
  if ( file )
  {
     char line[80];
     while ( file.getline(line, sizeof line) )
     {
        std::cout << line << '\n';
     }
  }
  return 0;
}

Copy this source into "file.txt" and it will print out this code.

Further Reading:
http://www.parashift.com/c++-faq-lite/input-output.html#faq-15.2
http://www.parashift.com/c++-faq-lite/input-output.html#faq-15.3
http://www.parashift.com/c++-faq-lite/input-output.html#faq-15.4
http://www.parashift.com/c++-faq-lite/input-output.html#faq-15.5

Dave,
in your first example with

while ( !file.eof() ) // bad!!

I could not get the extra 10
I am using Dev-C++ and Windows XP

>I could not get the extra 10
Put a newline at the end of the file.

Put a newline at the end of the file ...
Didn't give me the extra 10.
Why should a newline give an extra 10?

Something is not right.

When I use:

void fum(int *array, size_t size)
{
   size_t i;
   /* Initialize array. */
   for ( i = 0; i < size; ++i )
   {
      array[i] = i;
   }
   /* Perform calculations. */
   for ( i = 0; i < size; ++i )
   {
      array[i] *= 2;
   }
   /* Print array. */
   for ( i = 0; i < size; ++i )
   {
      printf("%d,", array[i]);
   }
   putchar('\n');
}

int main(void)
{
   int myarray[25];
   foo();
   bar();
   baz();
   qux();
   fum(myarray, ARRAYSIZE(myarray));
   return 0;
}

<< moderator edit: added [code][/code] tags and indenting >>

I have several errors. This is the exact replica of one of the posts above.
I don't understand where is the mistake as all looks ok.


Thanks,
Steven Dale

That is a snippet. Did you copy and paste all of those parts together and #include <stdio.h>?

[edit]Or pick just the necessary parts for one of them?

#include <stdio.h>

#define ARRAYSIZE(x)  (sizeof(x)/sizeof(*(x)))

void fum(int *array, size_t size)
{
   size_t i;
   /* Initialize array. */
   for ( i = 0; i < size; ++i )
   {
      array[i] = i;
   }
   /* Perform calculations. */
   for ( i = 0; i < size; ++i )
   {
      array[i] *= 2;
   }
   /* Print array. */
   for ( i = 0; i < size; ++i )
   {
      printf("%d,", array[i]);
   }
   putchar('\n');
}

int main(void)
{
   int myarray[25];
   fum(myarray, ARRAYSIZE(myarray));
   return 0;
}

/* my output
0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,
*/

copy-paste :|

What is the use of size_t . When we can use int for the same work to do.

Ashwin Perti

A size_t is an unsigned integral type which is the result of the sizeof operator. The two are designed to go together. To me it's the type most suited to indexing an array (you don't need negative indexes, do you?).

Sure you could use an int and it will be correct 99.999% of the time -- I was just going for 100%. Plus, with an array of ints, I find it easier to see the index from the data if they're not just slopped together.

I could not understand how exactly we can change the dimension of the array dynamically. Size once taken cannot be changed during the course of the program.

Ashwin Perti

It is not in regard to changing an array's size dynamically. It is in regard to recompiling on different systems.

I think you ppl lost me there. I am not a wizard, however I do used to belive you can change the size during the program is running .


Clara Ventures
www.cellforum.net

um how does the vector in c++ compare to the vector in physics

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.