Duoas 1,025 Postaholic Featured Poster

I notice you are spamming the forum with a lot of questions that you could easily get the answer to by simply reading the documentation or simple searches on Google.

What about my answer to this same question needs you to start another thread to ask it again?

Ahmad Imran commented: thats not spamming thats testing bro +0
Duoas 1,025 Postaholic Featured Poster

No. All (normal) messages go to a window event handler.

The functions you write to handle events can, of course, be as window agnostic as you like.

cambalinho commented: thanks +3
Duoas 1,025 Postaholic Featured Poster

To be clear, no, you cannot override static methods. (You can overload them, though.)

The reason is simple: a static method cannot appear in a class's virtual function table, so it is not inherited. In order to call a static method you must know exactly what type of object you are calling it from.

A quick example:

#include <iostream>

struct Foo
{
  static void speak()
  {
    std::cout << "Hello\n";
  }
};

struct Bar: public Foo
{
  static void speak()
  {
    std::cout << "No.\n";
  }
};

int main()
{
  Foo* baz = new Bar;
  baz->speak();
}

Give it a run.

Even though it is actually a Bar you've got, the compiler sees that you've got a pointer to a Foo and calls Foo::speak().

What would you have to do to make it say "No"?

That's right. Cast.

static_cast <Bar*> (baz)->speak();

By now, you may wonder if using the pointer stuff isn't overkill.

Well, actually, it is. You might as well just call the static methods directly.

Foo::speak();
Bar::speak();

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

Looks like a bug to me. Addition of pointers is both nonsensical and illegal in C. I see what the author was going for, but it seems especially awkward. I'd rather just keep a running count of the string length and set block to the current null character on each iteration. It's much simpler that way:

You're correct. While addition of pointers is illegal, even if you fixed it, there's still a logic error in that line.

Pointer arithmetic is not illegal. What is illegal is to perform arithmetic on unrelated pieces of memory. The pointer arithmetic was not a mistake; however I could have been more careful to code it as:

block  = ok + (size_t)(block - result) - 1;

Since you are in to giving a code review, I'd sure like to know exactly what the logic error is in that line. It seemed me some pretty simple addition for me that kind of error.

Also, I don't think that there is any point in keeping an extra variable around to track information that is already available in (block - result) . If I were developing under some specific company guidelines that addressed stuff like that I could easily adjust to do just as you would. Otherwise it comes down to nothing more than simple, personal preference.

as i see - this original auther code won't work at all (even without bug about which line we spoke earlier ...

Those are pretty careless statements to …

vedro-compota commented: + +3
Duoas 1,025 Postaholic Featured Poster

LINE_MAX is an IEEE extension to the standard <limits.h>, found on some *nix systems. TurboC does is older than, and does not follow, Open Group specifications.

The proper way to do what you want is to use a stack-local variable:

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

#define MY_MAX 1000

int main()
{
  char inputstr[ MY_MAX ];
  printf( "%s", "\nPlease enter your input string\n" );

  /* Get your input string */
  fgets( inputstr, MY_MAX, stdin );

  /* Get rid of the trailing newline, if any.
     (Notice that this doesn't consider the 
     possibility that the user input a string
     larger than your available buffer. */
  char* newline = strchr( inputstr, '\n' );
  if (newline) *newline = '\0';

  printf( "%s%s%s", "Good job! You entered \"", inputstr, "\"!\n" );

  return 0;
}

BUFSIZ is declared in <stdio.h> if you want to use that, but it doesn't really correspond with what you are doing.

The problem with C I/O is that the only safe method is fgets(), but it is a pain to work with directly. There exists the GNU readline library, which helps you with this very easily (and gives the user input editing powers), but if you need you can roll your own simple version, like I did here.

Other issues:

The character '' doesn't exist. You must specify a value between the quotes. If you want the null character, use '\0' .

Unless you are doing something very specific, you don't need …

vedro-compota commented: ++++++++++++++++ +3
Duoas 1,025 Postaholic Featured Poster

Er, I don't know if modern versions of Delphi support PNG out of the box. (I use an older version.)

If it doesn't, I recommend you get PngDelphi by Gustavo Doud.

If it does, then you are doing something wrong. Show your code.

Duoas 1,025 Postaholic Featured Poster

You should have yourself a little class that represents your data, and overload the extraction operator to handle it.

Since I was really bored today, I wrote a program for you. Change the parts you need to match your assignment.

Notice that there are several classes in use here.

  • date_t
    A very simple date-handling class. There are a lot of other ways it could have been implemented, including simply wrapping the <ctime> stuff, but I wanted to play. It demonstrates some useful STL usage...
  • certificate_t
    This is your certificate data. Notice that it is templated on whether or not you wish to print verbosely, since I did not know how you want your data output. (If that is overload for you, then just delete all the "verbose" stuff.) The difference is in the insertion operator beginning on line 255, where you can see the if statement choosing based on what to print. I also had to overload the default and copy constructors for the class in order to be able to change a non-verbose certificate into a verbose one. Again, there are other ways to do this, this is just one.
  • expired
    This is a little helper class to select through the list of certificates. See main() for how it is used.

A couple of other things to note:

  • Insertion (<<) operators are tricky things to play with. Notice how I output to a stringstream and then send that to the …
m4ster_r0shi commented: cool (^_^) +7
mike_2000_17 commented: you should ask for a pay check! +11
Duoas 1,025 Postaholic Featured Poster

>>Don't #include C header files in your header files

Oohh I didn't know it's wrong to do that.

It isn't wrong to do that.

You don't want to #include anything more than you absolutely must, but the whole point of #includes is to make stuff work.

How, for example, would the <sstream> header be able to specify anything useful without #including <string> ? You would have to duplicate information, and that is worse...


I always explain namespaces like having two friends named Jennifer. One is Jennifer Logan and the other is Jennifer Warner. When neither is present, I need to indicate that I am speaking about one or the other by using her full name. When one is present, I just call her "Jennifer", and I refer to the other by her full name. If both are present, I must again specify exactly who I mean.

Hope this helps.

Mouche commented: Awesome analog for namespaces. +6
Duoas 1,025 Postaholic Featured Poster

Do you mean that you are trying to handle something like when the user enters "flubbix" instead of a number?

Make yourself a little function to get numbers from the user:

#include <iostream>
#include <string>
#include <sstream>

template <typename T>
std::istream& get_number( std::istream& ins, T& x )
  {
  // Read a line (terminated by ENTER/RETURN key press) from the user
  std::string s;
  std::getline( ins, s );

  // Get rid of any trailing whitespace
  s.erase( s.find_last_not_of( " \f\n\r\t\v" ) + 1 );

  // Read it into the target type
  std::istringstream ss( s );
  ss >> x;

  // Check that there is nothing left over
  if (s.length() == 0 || !ss.eof())
    {
    ins.setstate( std::ios::failbit );
    }

  return ins;
  }

//
// SOMETHING TO SEE IT WORK
//
int main()
  {
  using namespace std;

  double d;

  cout << "Enter a number> ";

  if (!get_number( cin, d ))
    {
    cout << "Hey! That was not a number!\n";
    return 1;
    }

  cout << "Good job! Your number was: " << d << ".\n";
  return 0;
  }

Remember the following cardinal rule:

The user will always press ENTER/RETURN at the end of every input!

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

Microsoft function names are not very creative (which is a good thing).

GetDC()

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

You will also need to explicitly instruct Windows to associate your port with a COM device. You can find instructions here.

Finally, you would be aware that only "COM1" through "COM9" are specifiable like that. If you associate a port with a larger device number, you'll have to specify it with a string like "\\\\.\\COM24" , as described in this article. The same string will work for the normal port numbers also, as in "\\\\.\\COM2" .

Hope this helps.

Ancient Dragon commented: nice useful info. +17
Duoas 1,025 Postaholic Featured Poster

You forgot give us your email so we can send it there after we have written your program.

Nick Evan commented: This thread makes me laugh :) +16
Duoas 1,025 Postaholic Featured Poster

On POSIX systems, use poll() (or select()) to check to see if there is user input pending.

On Windows systems, use WaitForSingleObject().

I know this example is for windows, but you can easily modify it to work using the POSIX equivalent (Kubuntu update hosed my system and I haven't fixed it yet, so I'm not going to mess with modifying this example today):

#include <iostream>
#include <string>
using namespace std;

#include <windows.h>

int main()
  {
  string s;
  HANDLE hStdIn = GetStdHandle( STD_INPUT_HANDLE );

  cout << "I am going to count to 10.\n"
          "Press ENTER at any time to stop.\n";

  for (unsigned counter = 1; counter <= 10; counter++)
    {
    cout << "\r   \r" << counter << " " << flush;

    // Wait for one second on the standard input.
    // If standard input is waiting, we're done.
    if (WaitForSingleObject( hStdIn, 1000 ) == WAIT_OBJECT_0)
      {
      cout << "\r   \r> ";
      getline( cin, s );
      break;
      }
    }

  if (!s.empty())
    {
    cout << "(You entered \"" << s << "\".)\n";
    }

  cout << "OK. All done.\n";

  return 0;
  }

This kind of "is keypressed" function is easy to do:

#include <windows.h>

bool iskeypressed( int ms )
  {
  return WaitForSingleObject(
    GetStdHandle( STD_INPUT_HANDLE ),
    ms
    );
  }
// POSIX
#define INFINITE (-1)

#include <unistd.h>
#include <poll.h>

bool iskeypressed( int ms )
  {
  struct pollfd pls;
  pls.fd = STDIN_FILENO;
  pls.events = POLLIN | POLLPRI;
  return poll( &pls, 1, ms );
  }

On older BSD systems you may have to …

MrYrm commented: thanks for the great info +1
Duoas 1,025 Postaholic Featured Poster

Your professor is a jerk. (Anyone who would instruct his students to do something before doing it himself the same way students would is a jerk.) Using system( "color 1B" ); doesn't work -- that modifies the color of the entire console window.

Since you are on Windows, there are two (good) options to you. The first is to use the Win32 SetConsoleTextAttribute() function like vmanes instructed you. You can set both foreground and background colors with it.

Here is an example program:

#include <iostream>
#include <limits>
using namespace std;

#include <windows.h>

int main()
  {
  HANDLE hStdOut = GetStdHandle( STD_OUTPUT_HANDLE );
  WORD color;
  CONSOLE_SCREEN_BUFFER_INFO csbi;

  GetConsoleScreenBufferInfo( hStdOut, &csbi );

  for (unsigned f = 0; f < 16; f++)
    {
    for (unsigned b = 0; b < 16; b++)
      {
      // On Windows, the color is just this: very easy to calculate.
      color = (b << 4) + f;
      SetConsoleTextAttribute( hStdOut, color );
      cout << " A ";
      }
    SetConsoleTextAttribute( hStdOut, csbi.wAttributes );
    cout << endl;
    }

  cout << "Press ENTER to quit..." << flush;
  cin.ignore( numeric_limits <streamsize> ::max(), '\n' );

  return 0;
  }

(Clearing the screen is another trick. See here or here for more.)


The other option is to use the Curses library, which is a portable terminal handling library. For Windows versions, check out PDCurses.

Here is a sample program that uses it:

#include <curses.h>

int main()
  {
  int f, b, color_index;

  initscr();
  start_color();

  for (f …
Duoas 1,025 Postaholic Featured Poster

Sigh. Why is it that C++ questions always degenerate into C questions?

@firstPerson
Your code does not satisfy the OP's requirements. If the OP searches for the word "Hello" in the string "Hello, world!", your code cannot find it because it only delimits on whitespace (which would get the string "Hello," from the file, not "Hello").

You can recover somewhat from this by "trimming" the unwanted characters from the ends of every word you find, but it will not help when you read "one,two,three,four" from the file and wish to find "four".

@FatimaRizwan
If that is not a concern, then firstPerson's solution, plus the "trim" function, ought to be enough to get you going.

If it is a problem, keep reading.

But first, if you want to use C++, please get rid of the C stuff. It will only hurt you later when you fail to learn to do things the right way now.

Granted, this is probably a silly homework assignment, and what follows may be fully ignored. Well, at least I gave it something.


Tokenizing
Even though this is a fairly old concept it is still very much needed and used.

The way that strtok() does it is, shall we say, simplistic. However, we will continue with that model in mind. (Also, I will keep things simple by sticking with the std::string and std::istream data types.)

First, in order to get substrings from a string, …

jonsca commented: Above and beyond! +1
Agni commented: Very helpful code !! +3
Duoas 1,025 Postaholic Featured Poster

He has #include <windows.h> , so I believe we can safely assume some things about his operating environment.

On Windows, to wait for an event with a timer, use WaitForSingleObject() with the console input handle specified as the signal object. You'll need to use GetStdHandle().

bool countdown( int& seconds )
  // Displays a countdown timer from 'seconds' downto zero.
  // Returns true if the countdown made it to zero.
  // Returns false if the user pressed a key (which still needs to be read).
  // After the countdown returns, 'seconds' indicates how many seconds still remain to be counted.
  {
  HANDLE hStdIn = GetStdHandle( STD_INPUT_HANDLE );

  cout << "Press any key to abort the countdown.\n";
  for (; seconds; seconds--)
    {
    cout << "\r  " << n << flush;
    if (WaitForSingleObject( hStdIn, 1000 ) == WAIT_OBJECT_0)   // 1 second == 1000 ms
      {
      // The standard input object was signalled, meaning that input is waiting.
      return false;
      }
    }
  // The countdown hit zero. Display that and return success.
  cout << "\rDone!\n";
  return true;
  }

By the way, you should be using ReadConsoleInput() instead of getch()/getchar()/variants.

Also, I just gave you are really big bone. Keep in mind that it is not the whole solution to your homework problem. You still must understand what it is doing and use it properly.

As a hint, your program should be working in a loop to read key presses from the user, and only use the countdown if the user …

Duoas 1,025 Postaholic Featured Poster

^D terminates input. Hence, you cannot read it from the terminal directly (unless you modify the terminal's input state -- which I don't recommend).

If you are sure you are reading from the terminal, you can simply say:

string text;
  cout << "Please enter a bunch of lines. Press Ctrl-D to stop.\n";
  getline( cin, text, char(0) );  // any non-readable character will do
  cin.clear();

Thereafter you can continue to use cin.

Here is a moderately useful little function for you:

#include <cctype>
char Ctrl( char c )
  {
  return std::toupper( c ) - 'A';
  }

You can use it above in like manner: getline( cin, text, Ctrl('D') ); . You can use this version to read from your file too. (And don't forget to clear().)

To write a control character to file, just do:

cout << text << Ctrl('D') << flush;

Just be aware that if you want to read or write a ^M or a ^J to file, it must be opened in binary mode.

Be sure to check to see if you are operating from a terminal (human) or from a device (redirected input), using isatty(), and if it is not a terminal, an EOF really means EOF.

Finally, please be aware that such code will not compile/work on foreign systems (such as Windows).

Hope this helps.

DarkC0de commented: thanks +1
Nick Evan commented: Nice post +12
Duoas 1,025 Postaholic Featured Poster

Nice. The only problem is that you can have overflow, which would destroy the values of the variables. Use bitwise operations instead:

a ^= b;
b ^= a;
a ^= b;

Enjoy.

Duoas 1,025 Postaholic Featured Poster

I suggest you take a read through The Function Pointer Tutorials, particularly this one.

I would use some typedefs to help:

typedef float (char2float_t)( char );
typedef char2float_t* int2char2float_t( int );

...

char2float_t* wonky_function_1( int n )
  {
  ...
  }

...

int2char2float_t* fp1 = &wonky_function_1;

char2float_t* fp2 = fp1( 42 );  /* or: fp2 = (*fp1)( 42 ); */
float value = fp2( 'A' );       /* likewise: value = (*fp2)( 'A' ); */

BTW, you really are doing something weird. What goal can you possibly be trying to accomplish? (It appears to me that there is a design flaw in your program.) Perhaps we can suggest something better (and easier).

Also, this is the C forum. You are using C++.

Salem commented: Excellent stuff +36
Duoas 1,025 Postaholic Featured Poster

Sorry I was so grouchy.

iamthwee commented: get some R and R baby. +22
Duoas 1,025 Postaholic Featured Poster

Sorry to respond to this late... but I wanted to post info also...

The getline() function has the obnoxious habit of returning a not good() stream for final blank fields...

For a single blank line at the end of input, that's fine... (there's no record) but for blank fields it makes a difference. You can get past the problem by checking the stream state before getting a line.

For simple CSV files (meaning you cannot use the ';' character [or whatever character you've chosen] in the field value) this is a working example:

#include <deque>
#include <iostream>
#include <sstream>
#include <string>

typedef std::deque <std::string> record_t;
typedef std::deque <record_t>    table_t;

std::istream& operator >> ( std::istream& ins, table_t& table )
  {
  std::string s;
  table.clear();

  while (std::getline( ins, s ))
    {
    std::istringstream ss( s );
    record_t           record;
    std::string        field;
    bool               final = true;

    while (std::getline( ss, field, ';' ))
      {
      record.push_back( field );
      final = ss.eof();
      }
    if (!final)
      record.push_back( std::string() );

    table.push_back( record );
    }

  return ins;
  }

This will allow you to read all seven fields in a record like:

one; two;three;four;;six;

Hope this helps.

Ancient Dragon commented: Great example :) +36
VernonDozier commented: Haven't seen you in a while. Nice post. +19
iamthwee commented: welcome back blender man +22
Nick Evan commented: Nice :) +22
Duoas 1,025 Postaholic Featured Poster

I agree with AD that the FTP is probably what is going wrong.

FTP defaults to text mode. You must explicitly set it to binary mode before copying files.

tux4life commented: Yes. +12
Duoas 1,025 Postaholic Featured Poster

The wait() function monitors the state of a process, not its I/O streams. What you really want is the poll() or select() function.

It also seems that you want unbuffered input on your end of the pipe. See termios(3) for more.

See also poll(3) and select(3) for good reading on how these functions are used.

Hope this helps.

Salem commented: Some good old fashioned RTM - excellent +29
Duoas 1,025 Postaholic Featured Poster

Alas, I just googled it.

Try searching for things like "bresenham line circle ellipse algorithm".

Speed comes from doing the least to draw individual pixels. Hence, a lot of optimization comes from low-level accesses. In modern GUI architectures, often the case is for pixel access to occur in memory (in-memory bitmaps/pixmaps and the like), and then have the WM/OS/whatever copy the image to the graphics hardware. When you move to more direct accesses (like DirectX, etc.) then you must minimize accesses to the hardware yourself -- since it is slower than normal memory accesses.

Hope this helps.

Salem commented: Sounds good to me +29
Duoas 1,025 Postaholic Featured Poster

I just can't fathom why truly brain-dead things like system("PAUSE") keep being taught.

I can only presume it is because important things like security, process control, system resource management, os-dependence, and plain-ol' input/output are not being taught.

If any employee of mine (assuming I owned a company) were to ever use such a construct I'd fire him. Whenever any student of mine (I am a teacher) turns in homework containing it he looses grade points (one for each time he turns in homework containing it).

Oh, apparently I also have to mention that this thread is over a year old...


(I regret having ever suggested that it can be used for any reason at all... even stupid stuff.)

Makes me want to unplug your computer with a pair of dikes.

StuXYZ commented: Sanity when teaching ! Thx! +4
Duoas 1,025 Postaholic Featured Poster

Yes, you really are asking an OS and SDK-dependent question.

If you are using something like SDL, then respond to the key events that SDL gives you. Most GUI/graphics toolkits will give you a way to hook into keyboard events.

If you are using straight Win32, look for WM_KEYDOWN events in your message loop.

If you are using X, make sure you have selected an appropriate KeyPressMask and watch for KeyPress events in your main event loop.

If you are using something else, please let us know.

Alex Edwards commented: I knew it - thanks for the thorough explanation =) +4
Duoas 1,025 Postaholic Featured Poster

Good grief. Only use TerminateProcess() to kill the unruly.

Otherwise, just ask it nicely: send it a WM_CLOSE message. If it doesn't respond in, say, 500 ms or so, use CreateRemoteThread() and ExitProcess(). If it still doesn't quit after another half-second or so, then swat it with TerminateProcess().

Hope this helps.

Salem commented: Much better ideas +21
Duoas 1,025 Postaholic Featured Poster

If you read and write your files one byte at a time, endianness is not an issue.

However, bit order is always an issue. The first bit you write should be in bit position 0 of the first byte you write. The second bit goes in bit position 1, etc. The ninth bit goes in position 0 of the second byte. Etc.

I'll use that little huffman tree from the Wikipedia.

space a     e     f     h     i     m     n      
111   010   000   1101  1010  1000  0111  0010  
s     t     l     o     p     r     u     x      
1011  0110  11001 00110 10011 11000 00111 10010

Now the thing to remember here is that each code is a list of bits. Hence you have to read the above bitstreams from left-to-right, which is opposite from our usual way of looking at numbers.

For example, the 'h' is code '1101', which we can store as the number 11 --not 13. The way we are writing it here is with the lsb on the left and the msb on the right. Hence: 1 + 2 + 0 + 8 = 11 This becomes important when we start sticking more than one code next to each other. Since the order of the bits is important (not the numbers!), we must always read left-to-right, least-significant-bit to most-significant-bit.

An example: Bitsequence of a p p l e

The bitstream a..p....p....l....e.. 010100111001111001000 Separate it into bytes byte 0 . . byte 1 . …

Nick Evan commented: Respect for the amount of time you put into this +9
Duoas 1,025 Postaholic Featured Poster

You need to keep track of how many bits you have "output" so far. When you get eight or more, output a byte.

unsigned char bits = 0;  // the unwritten bits
int count = 0;  // the number of unwritten bits

// write_bit()
//    Write a single bit to the output stream
//
void write_bit( ostream& outs, bool bit )
  {
  // Add the latest bit into our "to-output" bits
  bits |= bit << count;

  // Track how many we have "output" so far
  if (++count < 8) return;

  // If we have "output" a whole byte, then
  // actually write it to the output stream
  outs.put( bits );

  // And reset
  bits  = 0;
  count = 0;
  }

// flush_bits()
//   Write any left-over bits --filling
//   with zeros to the even byte.
//
void flush_bits( ostream& outs )
  {
  if (count) outs.put( bits );
  bits  = 0;
  count = 0;
  }

I'm not sure how exactly you plan to avoid the STL in C++. The solution would be much nicer if you were to use it... but the above demonstrates the basics.

Notice how since we are dealing with a bit-stream, we must output bits in the same order as we get them -- meaning:

bit #   byte 1    byte 2
  1       .......@  ........
  2       ......@x  ........    These bytes are DISPLAYED
  3       .....@xx  ........    in the way that we humans
  4       ....@xxx  ........    like to read them, but what
  5       ...@xxxx  ........    is really …
AutoC commented: awesome +1
Duoas 1,025 Postaholic Featured Poster

Google "mingw sdl" and take a look through the first few links.

If you haven't already, make sure to upgrade to the latest version of MinGW (Dev-C++ comes with a pretty old one).

Good luck!

Alex Edwards commented: Yes, I'e been bitten in the ass with ol' Mingw so many times @_@ +4
Duoas 1,025 Postaholic Featured Poster

Yes, it is an encoding issue. I suspect that it comes from the way your editor is saving the text file.

There are several ways to 'encode', or store, character data.

There is the old char-sized ASCII encoding, but that is limited to only 7-bit ASCII characters and any system dependant character codes above 127. Microsoft calls this "ANSI" and the exact selection of extended characters depends on your output code page. Obviously, this is not very convenient for languages using anything but straight-up Roman characters.

Then came (eventually) Unicode, which handles all language graphemes. (This doesn't mean it is complete --additions are still being made, but most industrialized nations can express their native language[s] with Unicode.)

There are several ways to store Unicode: three of which are of interest to us.

UTF-8 uses our venerable char. Only those graphemes that need more than one byte use more than one byte.

UTF-16/UCS-2 variable-width characters, like UTF-8, but where the smallest element is a 16-bit word instead of a byte. This format is considered deprecated, but it is still very much in use.

UTF-32/UCS-4 simply stores every character in a 32-bit word. This is how the GCC treats Unicode (wchar_t) values. As such, modern Linux systems in general are moving toward the exclusive use of this encoding.


So, now that you've had the lecture, on to the point: your text editor is using UTF-8, which you will recall is variable-width. I …

Nick Evan commented: Very good post +8
Duoas 1,025 Postaholic Featured Poster

No, it is the same as all the files having a #define GRAPHICS To have a value: g++ -DGRAPHICS=1 --> #define GRAPHICS 1 if (GRAPHICS) will work if and only if GRAPHICS is always defined to have some value (such as 0 or 1). That is typically a wasteful way to do it though, because you add time used and space occupied for every test. It is best to stick with the #ifdef GRAPHICS so that only the code you need gets compiled into the executable.

[edit]
You can still test for different values though:

#if GRAPHICS == 1
  do_x();
#elif GRAPHICS == 2
  do_y();
#else
  do_z();
#endif

Hope this helps.

Salem commented: Both good answers. +20
Duoas 1,025 Postaholic Featured Poster

Empty files will never do anything except exist. ("Existing is basically all I do!" --Fry)

It also sounds like there is something misconfigured with your Code::Blocks IDE. Have you been able to compile other projects? Are you using a compiler other than MinGW?

If no to one or both of those:

  1. From the main menu select Settings|Compiler and debugger...
  2. Make sure your Selected compiler is the compiler you plan to use.
    Mine is the "GNU GCC Compiler" option.
  3. Click the Toolchain executables tab.
  4. Make sure the Compiler's installation directory is correct.
    I keep my MinGW in C:\Program Files\MinGW , but most users will have it in the default installation path: C:\MinGW If you are using another compiler, for example, CodeGear Turbo C++ Explorer, make sure you've got its installation directory listed C:\Program Files\Borland\BDS\4.0
  5. In the Program Files tab, make sure each item correctly identifies the executable. Mine uses all the default stuff for GCC:
    C Compiler:			mingw32-gcc.exe
    C++ Compiler:			mingw32-g++.exe
    Linker for dynamic libs:	mingw32-g++.exe
    Linker for static libs:		ar.exe
    Debugger:			gdb.exe
    Resource compiler:		windres.exe
    Make program:			mingw32-make.exe

    Again, if you are using something different, make sure you've got the correct executables. For TC++Explorer you'll want to make sure you've got something like:

    C++ Compiler:			bcc32.exe
    Linker for static libs:		ilink32.exe
    Resource compiler:		brcc32.exe
    Make program:			make.exe

    Et cetera.
    If you aren't using the GCC you'll also want to make sure you've got the proper global variables set up. See here for more.

OmniX commented: One of the most helpful posts. Thankyou. +1
Ancient Dragon commented: Excellent :) Also works in VC++ 2008 Express +36
Comatose commented: Very Much On Point! +12
Duoas 1,025 Postaholic Featured Poster

Wait... this is marked as solved?

Console programs can have any and all of the same resources as Window GUI programs, but they typically aren't built with them. On Windows, EXE, DLL, OBJ, and a few other files are all the PE32 file format.

For MinGW users in general, you need to create an RC file, like:

MAINICON ICON "foo.ico"

Then use windres to compile it to a linkable object file: C:\prog\foo> windres fooicon.rc fooicon.o When you compile, just link it into the exe as usual: C:\prog\foo> g++ foo.cpp fooicon.o For Code::Blocks users, you only need to go so far as to create the RC file and add it to your project. The IDE can handle compiling it correctly.

Have fun!

Duoas 1,025 Postaholic Featured Poster

In addition, you should have a removeBook() (or some such named) method(s) for the user's convenience.

Undertech commented: It's a good idea although I wouldn't be able to implement it for this particular assignment. +1
Duoas 1,025 Postaholic Featured Poster

Use the STL

#include <algorithm>
#include <fstream>
#include <iostream>
#include <iterator>
using namespace std;

int main( int argc, char** argv )
  {
  if (argc < 2)
    {
    cout << "usage:\n  countlines FILENAME\n";
    return 0;
    }

  ifstream file( argv[ 1 ] );
  if (!file)
    {
    cerr << "Could not open file \"" << argv[ 1 ] << "\"\n";
    return 1;
    }

  file >> noskipws;
  cout << count(
            istream_iterator <char> ( file ),
            istream_iterator <char> (),
            '\n'
            )
          +1  // the last line is not terminated by NL
       << endl;

  return 0;
  }

Hope this helps.

Ancient Dragon commented: I like it -- although slightly obscure. +35
Duoas 1,025 Postaholic Featured Poster

With just a very quick glance, that notOptimized() function needs some help. A bitvector (or vector<bool> ) is not a good choice in such a function. Sad, but it was optimized for space, not speed.

If each point of a quad is always optimized or unoptimized, you can reduce it to a single bit. I don't know if you can do that though.

The other way would be to make yourself an array of bytes that are themselves bit fields representing the points of a quad. The overhead of handling it that way wouldn't be much different than the overhead of your bitvector (since each quad stores its own copy of the vertex's optimization state anyway), but your function could then just directly index the quad's optimization byte and compare that to 0x0F. If equal, all are optimized. If not, then at least one is not optimized.

That function is called so often that it is worth every millisecond you can squeeze out of it.

The rotateFour() function is pretty good as-is, but believe it or not you might get better results if you were to use the <cstring> memmove(), or just as good (I think) but easier to use,

register int n = x[ 3 ];
char_traits <int> ::move( x+1, x, 3 );
x[ 0 ] = n;

If that is unsatifactory, it might be worth writing it in assembly yourself.

Finally, I don't know why you are using new so much, but …

Alex Edwards commented: Very interesting post. Gave me something to think about =) +3
Duoas 1,025 Postaholic Featured Poster

Without even looking at your code, I will make a wild stab in the dark and say that you are using a Windows console to run your program?

If you are, right-click the icon on the console's title bar and select "properties" from the drop-down menu. Click the "Layout" tab and play with the items in the "Screen Buffer Size" panel until you are content. My own console windows are set to have a buffer Height of 300 lines. Once done, click "OK" and click "Modify shortcut that started this window", and hit "OK" once more.

If that wasn't the problem... let me know.

William Hemsworth commented: Good guess >.< +3
Duoas 1,025 Postaholic Featured Poster

semicolons
A semicolon by itself is considered a null statement, and has no meaning. Modern compilers will typically complain about them unless they explicitly terminate a statement. For example int number_of_lightbulbs_to_change; ; That second semicolon, while probably not an error, is also not useful, so the compiler will complain. It could be an error: if (foo == mane) padme(); ; else hum(); For counter-example for (int n = 0; quux( n ); n++); This last semicolon is in fact a null statement, but it has a purpose: it expresses an empty loop body.

data initializers
Whether or not you can specify an initializer depends on whether or not the file is #included in another.

// foo.hpp
#ifndef FOO_HPP
#define FOO_HPP
namespace foo
  {
  extern const int fooey;
  }
#endif
// foo.cpp
#include "foo.hpp"
namespace foo
  {
  const int fooey = 42;
  }

This is to obey the One Definition Rule.

when to use using
The difference between header files and object source files is important also when using namespaces. In a header file, you should never (and yes, this is one of those rules), never add stuff to the global namespace. It is not your perogative to decide what the person using your library permits in his namespaces. Example:

// bar.hpp
#ifndef BAR_HPP
#define BAR_HPP

#include <iostream>
#include "bazlib.hpp"

using namespace std;  // <-- WRONG! JUST SAY NO!

using baz::buzz;  // <-- WRONG! JUST SAY NO!

#endif

The reason should …

VernonDozier commented: Good summary +5
William Hemsworth commented: Thats a nice big post :) +3
Prabakar commented: Yes, Really nice:) +1
Duoas 1,025 Postaholic Featured Poster

Heh heh heh -- I couldn't resist iamthwee's challenge (sorry conan --look below for where to get a dictionary).

// boggle-solver.cpp
// Copyright (c) 2008 Michael Thomas Greer
// <http://www.boost.org/LICENSE_1_0.txt>

#include <algorithm>
#include <fstream>
#include <iostream>
#include <iterator>
#include <string>
using namespace std;

char gameboard[ 4 ][ 4 ];

bool validate_word( const string& word, int row, int col, int index, int touched )
  {
  if ((unsigned)index == word.length()) return true;
  for (int r = -1; r < 2; r++)
  for (int c = -1; c < 2; c++)
    {
    int mask = 1 << (((row +r) *4) +col +c);
    if (((touched & mask) == 0)
    &&  (gameboard[ row +r ][ col +c ] == word[ index ]))
      if (validate_word( word, (word[ index ] == 'q') ? index +2 : index +1, row +r, col +c, touched | mask ))
        return true;
    }
  return false;
  }

void process_word( const string& word )
  {
  if ((3 > word.length()) or (word.length() > 17)) return;
  for (int row = 0; row < 4; row++)
  for (int col = 0; col < 4; col++)
    if (gameboard[ row ][ col ] == word[ 0 ])
      if (validate_word( word, row, col, 1, (row *4) +col ))
        cout << word << '\n';
  }

int main()
  {
  cerr << "Enter the gameboard. Use just 'Q' for 'Qu'.\n";
  for (int n = 0; n < 16; n++)
    *((char*)gameboard +n) = tolower( (cin >> ws).get() );

  ifstream words( "word.lst" );
  if (!words) return 1;
  for_each( istream_iterator <string> ( …
iamthwee commented: I challenge you to solve Riemann's Hypothesis next. +15
Duoas 1,025 Postaholic Featured Poster

Actually, putting that system pause in there contributed to my low opinion. You said that was an example of when he uses <cstring>.

gets() is pure evil and should be lynched at every opportunity.

Using c-strings in a C++ program, outside of any need to interface with legacy code, is considered anachronistic and silly. It is kind of like building your own car to drive to the grocery --when a premade vehicle would cost less and be more convenient.

system( "anything" ) is resource heavy and a big security hole. It should not be taught as a convenience to do stupid or trivial stuff. I've nothing against using it in your own code, temporarily, to subdue your IDE, but it shouldn't ever find its way into production code. In the case of "pause", "cls", "title", etc, it also puts surprise restrictions on your program. Stream applications shouldn't demand human attention to operate.

Alas. C++ is a big world. And a lot of it is still stuck in C on MSDOS.

Duoas 1,025 Postaholic Featured Poster

How is your dictionary stored? If, like iamthwee suggests, it is a file with words in it, you can just search the file for the given word.

You can even use the STL for that:

#include <algorithm>
#include <fstream>
#include <iterator>
#include <string>

// findword()
//   Determine whether or not a given word exists in a file.
//   This routine assumes that no word has spaces in it.
// returns
//   True if the word was found. False for any other reason.
//
bool findword( const std::string& filename, const std::string& word )
  {
  bool result = false;
  std::ifstream file( filename.c_str() );
  std::istream_iterator <std::string> end;

  result =
    std::find(
      std::istream_iterator <std::string> ( file ),
      end,
      word
      )
    != end;

  result &&= file.good();

  file.close();
  return result;
  }

However, this requires a large file access every time. You could open the file elsewhere and just seekg( 0 ); before each search, or you could load the file into memory (into a std::deque or some other container) and search it there.

#include <deque>

std::deque <std::string>
loadwords( const std::string& filename )
  {
  std::deque <std::string> result;
  ifstream file( filename.c_str() );
  std::copy(
    std::istream_iterator <std::string> ( file ),
    std::istream_iterator <std::string> (),
    std::back_inserter( result )
    );
  file.close();
  return result;
  }

bool findword(
  std::deque <std::string> words,
  const std::string& word
  ) {
  return
    std::find(
      words.begin(),
      words.end(),
      word
      )
    != words.end();
  }

(Use a deque over a vector for this kind of thing.)

Hope this helps.

Duoas 1,025 Postaholic Featured Poster
#include <iomanip>
#include <iostream>
using namespace std;

int main()
  {
  for (int n = 1; n < 6; n++)
    cout << n;
  cout << setw( 5 ) << right << (167) << "mm\n";
  return 0;
  }

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

There is nothing more or less hard about C++ than any other programming language.

People fear C++ because it comes with a very large set of capabilities.

It can be used to program procedurally.
It can be used to program object-orientedly.
It can be used to program generically.
It can be used to program functionally.
It can be used for very low-level machine programming.
It can be used for very high-level abstract programming.
It can do all of the above at once.

It comes with a very large standard template library --which takes some time to get used to.
And it mixes very well with C, which is often a source of confusion for new programmers.

The core language is not large. But the vast capabilities of the language and the size of the STL can sometimes make it seem like a hulking beast.

You can read Bjarne Stroustrup's FAQs about the language at his site
http://www.research.att.com/~bs/bs_faq.html
You might want to give particular attention to the second section, but the entire document gives a lot of useful information.

Hope this helps.

Ancient Dragon commented: Excellent description :) +34
Duoas 1,025 Postaholic Featured Poster

In practice it doesn't impact performance.

What it does is make your code more usable, more correct, and easier to read.

All you ever wanted to know about const correctness
http://www.parashift.com/c++-faq-lite/const-correctness.html
http://cprogramming.com/tutorial/const_correctness.html
http://www.possibility.com/Cpp/const.html

For good measure, here's an example where it makes a difference:

#include <iostream>
#include <string>
using namespace std;

void reverse_print_const( const string& s )
  {
  cout << "const: ";
  for (string::reverse_iterator c = s.rbegin(); c != s.rend(); c++)
    cout << *c;
  cout << endl;
  }

void reverse_print_non_const( string& s )
  {
  // Take note that the function body is exactly the same as above
  cout << "const: ";
  for (string::reverse_iterator c = s.rbegin(); c != s.rend(); c++)
    cout << *c;
  cout << endl;
  }

int main()
  {
  string message = "Hello world!";

  // Both of these work just fine
  reverse_print_const( message );
  reverse_print_non_const( message );

  // But this fails for the non-const
  reverse_print_const( "!sseccuS" );
  reverse_print_non_const( "...eruliaF" );  // <-- this line won't compile!

  // The reason why is that the const char* is
  // type-promoted to a const string temporary
  reverse_print_const( string( "!edud suoethgiR" ) );
  reverse_print_non_const( string( "...remmuB" ) );  // <-- same here

  // We can test it the same with a const message
  const string message2( "Good-bye." );
  reverse_print_const( message2 );
  reverse_print_non_const( message2 );  // <-- same here

  return 0;
  }

What this should make clear is that the compiler is free to use the const version of the function in all circumstances, …

William Hemsworth commented: Good Post +2
Duoas 1,025 Postaholic Featured Poster

You'll also need to #include <iterator> if you want to use those back_inserters properly.

The lexicographical_compare() algorithm optionally takes a fifth argument: a boolean predicate. You can make your custom predicate do a case-insensitive comparison by converting both arguments toupper() before returning whether a < b.

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

Olvidaste poner conullas al seis. while (producto != '6') :$

Hope this helps.

VernonDozier commented: Showoff! :) +5
Duoas 1,025 Postaholic Featured Poster

I think you need to spend some time tracing through your algorithm. I'm not sure exactly what it is supposed to do, but I don't think it is doing what you want it to do...
(Given "HELLO", the list it builds is H, E, L, LL, ...)

In any case, your problems are with strncpy().
There is no guarantee that the result string (aux) will be null-terminated, and the way you are doing it, it definitely will not be null-terminated. Make sure to put a '\0' at the end of the string.

Hope this helps.

PS. I know some libraries (notably MS) typedef away *s from pointers, but that is really bad style. If you are using a variable, you should not have to find a typedef to know whether it is a pointer or not, and it makes reading the code harder. It took me a minute to verify that the last three lines of Insert() were doing what they were supposed to be doing...

Duoas 1,025 Postaholic Featured Poster

Ah, it is because seating is declared as a 2D array, but you are only indexing one dimension. Hence the error.

Did you mean to treat seating as a 1D array in your function? I'm not sure how you are trying to index the seating array in your function...

If I am reading it right (from just a quick glance over your code) it should be: if(seating[openRow][openSeat + potential] == '#') Hope this helps.

Duoas 1,025 Postaholic Featured Poster

OK, I told you I'd get you an example. I don't want to spend a lot of time finding the libraries to do it and coding one, but I do have an old program I wrote many many moons ago, when I was still new to programming. It is in Turbo Pascal, but you can translate the important parts to Turbo C++ easily enough. Just a couple notes for you:

  • uses Graph; corresponds to #include <graphics.h> Individual Borland graphics routines are named similarly (I think TC puts them all in lowercase though).
  • foo^ is the same as *foo
  • ReadKey corresponds to getch
  • { and } correspond to /* and */
  • Mark and Release are old Borland heap control procedures. I don't think TC has corresponding procedures... better for you to free() the image data manually.
  • The arrow keys move the background around. ESC quits.
  • The procedures of interest to you are: InitiateGraphics, FlipPages, ClearPage, and the main code block.
  • It is fairly heavily commented in my newbie style.

Ok, so here it is. (I use 80 column limits, but DaniWeb is shorter, so what you see following looks messy. Just click the "Toggle Plain Text" button to cut and paste something more readable.)

program GPImage;
uses Crt,Graph;
var
  GraphDriver, GraphMode    : integer;                { hardware refrences }
  WX1,WY1, WX2,WY2, MX2,MY2 : integer;{ window x1,y1, x2,y2, center of scr }
  CurrentPage               : integer;      { active, hidden graphics page }

  IMAGE_SIZE …