User Name Password Register
DaniWeb IT Discussion Community
All
What is DaniWeb IT Discussion Community?
You're currently browsing the C++ section within the Software Development category of DaniWeb, a massive community of 397,769 software developers, web developers, Internet marketers, and tech gurus who are all enthusiastic about making contacts, networking, and learning from each other. In fact, there are 2,483 IT professionals currently interacting right now! Registration is free, only takes a minute and lets you enjoy all of the interactive features of the site.
Please support our C++ advertiser:
Views: 50229 | Replies: 54
Closed Thread
Join Date: Sep 2004
Posts: 6,050
Reputation: Narue has much to be proud of Narue has much to be proud of Narue has much to be proud of Narue has much to be proud of Narue has much to be proud of Narue has much to be proud of Narue has much to be proud of Narue has much to be proud of 
Rep Power: 26
Solved Threads: 416
Super Moderator
Narue's Avatar
Narue Narue is offline Offline
Expert Meanie

C and C++ Timesaving Tips

  #1  
Mar 10th, 2005
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
}
Member of: Beautiful Code Club.
AddThis Social Bookmark Button
 
Join Date: Apr 2004
Posts: 3,462
Reputation: Dave Sinkula is a glorious beacon of light Dave Sinkula is a glorious beacon of light Dave Sinkula is a glorious beacon of light Dave Sinkula is a glorious beacon of light Dave Sinkula is a glorious beacon of light Dave Sinkula is a glorious beacon of light 
Rep Power: 16
Solved Threads: 138
Colleague
Dave Sinkula's Avatar
Dave Sinkula Dave Sinkula is offline Offline
long time no c

Re: C and C++ Timesaving Tips

  #2  
Mar 10th, 2005
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
Last edited by Dave Sinkula : Oct 14th, 2005 at 12:23 pm. Reason: Fixed iterator loop condition -- thanks Micko.
 
Join Date: Oct 2004
Location: Mojave Desert
Posts: 2,414
Reputation: vegaseat will become famous soon enough vegaseat will become famous soon enough 
Rep Power: 9
Solved Threads: 173
Moderator
vegaseat's Avatar
vegaseat vegaseat is offline Offline
Kickbutt Moderator

Solution Re: C and C++ Timesaving Tips

  #3  
Mar 11th, 2005
From the code snippet on the very same subject is another way to initialize a vector ...
[php]
// 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;
[/php]
May 'the Google' be with you!
 
Join Date: Oct 2004
Location: Mojave Desert
Posts: 2,414
Reputation: vegaseat will become famous soon enough vegaseat will become famous soon enough 
Rep Power: 9
Solved Threads: 173
Moderator
vegaseat's Avatar
vegaseat vegaseat is offline Offline
Kickbutt Moderator

Solution Re: C and C++ Timesaving Tips

  #4  
Mar 11th, 2005
How to remove duplicate elements from a vector ...
[php]
// 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;
...
[/php]
May 'the Google' be with you!
 
Join Date: Sep 2004
Posts: 6,050
Reputation: Narue has much to be proud of Narue has much to be proud of Narue has much to be proud of Narue has much to be proud of Narue has much to be proud of Narue has much to be proud of Narue has much to be proud of Narue has much to be proud of 
Rep Power: 26
Solved Threads: 416
Super Moderator
Narue's Avatar
Narue Narue is offline Offline
Expert Meanie

Re: C and C++ Timesaving Tips

  #5  
Mar 13th, 2005
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:
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.
Member of: Beautiful Code Club.
 
Join Date: Mar 2005
Posts: 13
Reputation: wbk is an unknown quantity at this point 
Rep Power: 4
Solved Threads: 0
wbk wbk is offline Offline
Newbie Poster

Re: C and C++ Timesaving Tips

  #6  
Mar 16th, 2005
Originally Posted by Narue
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;
}
 
Join Date: Sep 2004
Posts: 6,050
Reputation: Narue has much to be proud of Narue has much to be proud of Narue has much to be proud of Narue has much to be proud of Narue has much to be proud of Narue has much to be proud of Narue has much to be proud of Narue has much to be proud of 
Rep Power: 26
Solved Threads: 416
Super Moderator
Narue's Avatar
Narue Narue is offline Offline
Expert Meanie

Re: C and C++ Timesaving Tips

  #7  
Mar 16th, 2005
>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.
Member of: Beautiful Code Club.
 
Join Date: Mar 2005
Posts: 13
Reputation: wbk is an unknown quantity at this point 
Rep Power: 4
Solved Threads: 0
wbk wbk is offline Offline
Newbie Poster

Re: C and C++ Timesaving Tips

  #8  
Mar 16th, 2005
Originally Posted by Narue
>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.
 
Join Date: Sep 2004
Posts: 6,050
Reputation: Narue has much to be proud of Narue has much to be proud of Narue has much to be proud of Narue has much to be proud of Narue has much to be proud of Narue has much to be proud of Narue has much to be proud of Narue has much to be proud of 
Rep Power: 26
Solved Threads: 416
Super Moderator
Narue's Avatar
Narue Narue is offline Offline
Expert Meanie

Re: C and C++ Timesaving Tips

  #9  
Mar 16th, 2005
>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.
Member of: Beautiful Code Club.
 
Join Date: Dec 2004
Location: Devon - UK
Posts: 420
Reputation: 1o0oBhP is an unknown quantity at this point 
Rep Power: 4
Solved Threads: 6
1o0oBhP's Avatar
1o0oBhP 1o0oBhP is offline Offline
Posting Pro in Training

Re: C and C++ Timesaving Tips

  #10  
Mar 20th, 2005
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....
http://sales.carina-e.com

no www
no nonsense

coming soon to a pc near you! :cool:
 
Closed Thread

Only community members can participate in forum threads. You must register or log in to contribute.

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)

 

DaniWeb C++ Marketplace
Thread Tools Display Modes

Similar Threads
Other Threads in the C++ Forum

All times are GMT -4. The time now is 4:22 am.
Forum system based on vBulletin Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
©2003 - 2008 DaniWeb® LLC