Duoas 1,025 Postaholic Featured Poster

Or you could read one line at a time (or even the whole file) and use standard algorithms to remove digits:

#include <algorithm>   // remove_if()
#include <cctype>      // isdigit()
#include <functional>  // ptr_fun<>
#include <string>

...

string remove_digits( const string& s )
  {
  string result( s );

  result.erase(
    remove_if(
      result.begin(),
      result.end(),
      ptr_fun<int,int>( isdigit )
      ),
      result.end()
    );

  return result;
  }

Enjoy.

Duoas 1,025 Postaholic Featured Poster

That won't help to reduce/simplify fractions so much as using the Greatest Common Divisor.

Here it is with the Euclidean algorithm, unrolled one iteration.

int GCD( int a, int b )
  {
  while (true)
    {
    a = a % b;
    if (a == 0) return b;

    b = b % a;
    if (b == 0) return a;
    }
  }

So, to simplify a fraction, simply:

void simplify( int& n, int& d )
  {
  int gcd = GCD( n, d );
  n /= gcd;
  d /= gcd;

  // If negative, make it the numerator.
  if (d < 0)
    {
    n = -n;
    d = -d;
    }
  }

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

It isn't so much that the code itself is inefficient (aside from that it doesn't work);
It is the way you are trying to "do it the easy way" that is inefficient. What you think is easy will just send you in circles for days.

Do it right the first time (...............algorithm) and you'll get it right almost immediately.

Duoas 1,025 Postaholic Featured Poster

You should have gotten a runtime exception for trying it...

Anyway, Windows apps don't have consoles by default. At the beginning of your program you'll have to AllocConsole(); then... you'll have to hook the standard streams up to the console:
http://www.halcyon.com/~ast/dload/guicon.htm
(yoinks!)
Its easier than it looks.

Have fun.

VernonDozier commented: Good link. +2
Duoas 1,025 Postaholic Featured Poster

Hmm, sorry. I thought I responded to this already.

You'll have to set the DefaultDrawing property to false, and provide a method for the OnDrawCell event.

Here's an example I googled.
http://bcbjournal.com/bcbcaq/index.php?loc=grids&caq=48
(It is in BC++, but all the essentials are the same, so you shouldn't have any trouble reading it.)

Duoas 1,025 Postaholic Featured Poster

I've already given you all the help I can without giving you the answer. You have to use your brain now.

Think about what you know about converting binary to decimal, and apply the same logic to octal. Then try it and see if it works.

I suggest you write yourself a little function that takes a character and turns it into an integer or complains if it is invalid for the base. Its header might look something like this: [B]function[/B] CharToInt( c: [B]char[/B]; base: [B]integer[/B] ): [B]integer[/B]; Then you can say intCol := CharToInt( 'A', 8 ); If A is valid for octal (base 8) then intCol gets the value 10.
If A is not valid for octal then intCol gets the value -1 (invalid).
Etc.

Good luck.

Duoas 1,025 Postaholic Featured Poster

Display and UI are linked. Sorting (an underlying algorithm) is not.

The best CUIs provide maximum data display and minimum query display.

For example, your program may run something like this (bold represents user input):

% [b]a.out[/b]
Crush Yer Bones's College Project
Mr. Teacher
Algorithms, Spring 2008

Enter 'help' for help.
> [b]help[/b]

add     Add a record to the database
delete  Remove a record from the database
help    Enter 'help help' for how to use the help
list    List all records by title/sort criterion
open    Open a database file
quit    Quit
save    Save changes to the database
search  Search for a specific record
sort    Change the criterion used to sort and list the records
view    View an individual record

> [b]help help[/b]

Enter 'help' followed by the command for which you want
more specific information. For example:
  help view
displays how to use the 'view' command.

> [b]help view[/b]

View an individual record. Use it by entering
  view [OPTIONS]
where the OPTIONS are one or more of the following:
  INDEX  The integer index of the record to view
  NAME   The name of the record to view
  ...
If you fail to specify any required options you will be prompted
to enter them.

> [b]view[/b]
Enter the record index (ENTER if unknown)> [b]0[/b]
Valid record numbers are 1 to 7.
Enter the record index (ENTER if unknown)> 

> [b]list[/b]

1. Annette Johansen   5. Peter Moon
2. Billy Tsu          6. Roark Murphey
3. Miriam Leigh       7. Seanaed Murphey
4. …
Duoas 1,025 Postaholic Featured Poster

You might also benefit from reading through the Function Pointer Tutorials.

Duoas 1,025 Postaholic Featured Poster

Wow, sleep a little...

You would have a much easier time of it, and much more robust code, if you were to scrap all those if statements and use the algorithms I suggested to you.

Duoas 1,025 Postaholic Featured Poster

If he were programming on *nix he'd already know to just mount and open "/dev/fd0".
FindFirstFile, et.al. are straight-up Win32 API. :)

Duoas 1,025 Postaholic Featured Poster

I thought he was exceptionally clear. He posted his exact problem; gave nice, color-enhanced examples; and listed a nice, short code example that can be compiled.

Duoas 1,025 Postaholic Featured Poster

Google "msdn FindFirstFile", FindNextFile, FindClose.
For the path, just put the floppy's drive letter first, like "A:\*".

Duoas 1,025 Postaholic Featured Poster

You are very close.

You need to move line 22 up before line 19.
On line 19 you accidentally used the wrong variable. (Also, is the same as strDigit := strBin[[b][i]intLoop[/i][/b]] .)

The difference between binary (radix 2) and some other system is how much you multiply by on line 19.

Duoas 1,025 Postaholic Featured Poster

His assignment is to combine every two words thus:
<word0> <word1> --> <word0 replaces each consecutive sequence of digits in word1>

Duoas 1,025 Postaholic Featured Poster
Duoas 1,025 Postaholic Featured Poster

You are aware that my solution converts a string into an integer value compatible with your enum?

Duoas 1,025 Postaholic Featured Poster

Heh, well, at least you figured it out, even if you aren't aware that the solution is exactly as I predicted.

Duoas 1,025 Postaholic Featured Poster

STL to the rescue.

#include <algorithm>
#include <cctype>  // since you are using char*

...

bool str_eq_ci( const char* a, const char* b )
  {
  for (; *a && *b; a++, b++)
    if (std::toupper( *a ) != std::toupper( *b )) return false;
  if (*a || *b) return false;
  return true;
  };

...

const char *IncomingTCPCommandStrings[] = {
  "heartbeat",
  "publish",
  ...
  };

// Convert string into index:
TCPCommand = std::find_if(
              IncomingTCPCommandStrings,
              IncomingTCPCommandStrings+NUM_OF_TCP_COMMANDS,
              str_eq_ci
              )
            - IncomingTCPComandStrings;

This, of course, is very simplistic. You would be better off playing with std::string.
Further, if your enums aren't sequential, you'll be better off using a std::map().

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

Well, the best I can guess is that node is an incomplete type because it depends on T.

You'll have to ask your professor for more help.

Duoas 1,025 Postaholic Featured Poster

We won't do your homework or reply offline.

However, I can help you think through your problem.

A number is a number is a number is a number, no matter how it is represented for us humans. 10 dec == A hex == 12 oct == 1010 bin. The only difference is in the radix.

Common radices:
dec: base 10
hex: base 16
oct: base 8
bin: base 2

The radix is the difference between digit powers. In decimal:
1 == 1 * 10^0
10 == 1 * 10^1
100 == 1 * 10^2
1,000 == 1 * 10^3
etc.

The same is true in other radices. For example, binary:
1 == 2 * 2^0 (001b == 1 * 10b^0)
2 == 2 * 2^1 (010b == 1 * 10b^1)
4 == 2 * 2^2 (100b == 1 * 10b^2)
etc.

So, to convert between bases, you first need to decompose a human-readable representation from its radix into an actual number. Then you need to compose that number into the desired human-readable representation of a given radix.

For example: convert 1010 binary into a number:

str    := '1010';
radix  := 2;
number := (char_to_int( str[1] ) * pow( radix, 3 ))
        + (char_to_int( str[2] ) * pow( radix, 2 ))
        + (char_to_int( str[3] ) * pow( radix, 1 ))
        + (char_to_int( str[4] ) * pow( radix, 0 ));

Neither 'char_to_int' …

Duoas 1,025 Postaholic Featured Poster

You are trying to use a non-const iterator on a const reference. Use std::vector<std::string>::const_iterator it = tabNames.begin(); You might want to check out the tool referenced here to better understand those obnoxious STL error messages:
http://www.parashift.com/c++-faq-lite/templates.html#faq-35.17

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

The error is because somewhere in there you are trying to dereference a pointer whose value is NULL.

Without examples of OneClass and AnotherClass and exactly what method(s) you are calling to cause the error I cannot help further.

Duoas 1,025 Postaholic Featured Poster

Your syntax is correct, but you are probably not catching the correct thing. Usually the standard error is a descendant of runtime_error in <stdexcept>.

Take a read through http://www.parashift.com/c++-faq-lite/exceptions.html
and check 17.6 and 17.7.

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

Are you sure all your class declarations end with ';'?

Does your node class in any way depend on T?

Without more code I can't help further. Sorry.

Duoas 1,025 Postaholic Featured Poster

Recursion and iteration are two sides of the same coin.

The difference is, in C++, you have the potential of blowing your stack. So on Windows, if you have more than sizeof(Available RAM + Swap Space)/sizeof(Stack Frame) permutations, you'll crash your computer. Even if you don't get that high though... once you exceed RAM size your program will begin to slow considerably.

All that aside, recursion keeps state ("remembers" things) by passing and returning values.

As a simple example, the Fibonacci sequence is defined as:
F(0) = 0
F(1) = 1
F(n) = F(n-1) + F(n-2)

A simple iterative solution might look something like

unsigned long long i_fib( unsigned n )
  {
  switch (n)
    {
    case 0: return 0;
    case 1: return 1;
    default:
      unsigned long long f_of_n_minus_1 = 1;
      unsigned long long f_of_n_minus_2 = 0;
      unsigned long long f_of_n         = 1;
      for (; n > 1; n--)
        {
        f_of_n = f_of_n_minus_1 + f_of_n_minus_2;
        f_of_n_minus_2 = f_of_n_minus_1;
        f_of_n_minus_1 = f_of_n;
        }
      return f_of_n;
    }
  }

To make that recursive, we have to identify our state variables: F(n-1), F(n-2), F(n), and of course, n.
The current sum is dependent on the previous iterations, so that should be a return value, while everything else is dependent on 'n'.

So, that same routine in recursion would be

unsigned long long r_fib( unsigned n )
  {
  switch (n) 
    {
    case 0: return 0;
    case 1: return 1;
    default: return r_fib(n-1) + r_fib(n-2)
    } …
Duoas 1,025 Postaholic Featured Poster

That format is for use with running programs.

File times are stored as 64-bit FILETIME values. Use DateTimeToFileDate() and FileDateToDateTime() to convert between the two.

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

If you want to check file content, you'll probably want to look up a CRC algorithm. I believe you can find md5 code on the internet.

Duoas 1,025 Postaholic Featured Poster

When you first start your program, and every time you modify the file, remember its last modification date (you can get that with the stat() functions). Then just periodically check to see if the date has changed.

On Windows, you can use FindFirstChangeNotification() to create a notification object on a file or directory and use one of the wait functions, or you can use the ReadDirectoryChangesW() function.

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

Yes, just stick all your files in one directory and make sure only one file declares "main(".

You need to have the grep utility and gmake on your system. It will not work with other make programs.

To use it, just type gmake at the prompt.

Remember, this is just for simple projects. If you are compiling with anything unusual, like the math library or curses library or etc, you'll have to modify the "general options" section.

Enjoy.

Duoas 1,025 Postaholic Featured Poster

Actually, he's talking about preventing someone else's program from accessing the file system.

Check out your answer over at CodeGuru.

Duoas 1,025 Postaholic Featured Poster

Line 22: Random_Number() is a function. It needs to be followed by ().

On line 45: you didn't declare x and y's types. Your function header must match its prototype above exactly.

Use some math:

[ ][ ][ ] [ ][ ][ ] [ ][ ][ ]
 0  1  2   3  4  5   6  7  8   (x)
----0---- ----1---- ----2----  (x%3)

check( x, y ):

  int val = board[y][x];

  // check row
  for x0 = 0 to 8
    if (x0 != x)
      if (board[y][x0] >= 0)
        if (board[y][x0] == val)
          return false;

  // same kind of thing for column

  // check square:
  int square_y = (x %3) *3;
  int square_y = (y %3) *3;

  for y0 = 0 to 2
  for x0 = 0 to 2
    if (x0 != x) and (y0 != y)
      if (board[ square_y +y0 ][ square_x +x0 ] == val)
        return false;

  return true

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

You could always initialize the board to be filled with invalid values (like -1) which is excluded from all comparisons.

Your modulus idea is good.

Duoas 1,025 Postaholic Featured Poster

I don't imagine that recursion and permutations are very safe together without tail recursion.

Use a modulo counter. For example, in the Arabic number system we use we have ten digits for each power.
0 1 2 3 4 5 6 7 8 9

To count through them all, just start counting.

// Print 0123456789... ad infinitum
for (unsigned u = 0; ; u++)
  cout << (u % 10);

Take it one step further, and the thing you print doesn't actually have to be the digit, it can be anything you can index in a ten-element array.

// Print abcdefghij... ad infinitum
char letters[] = "abcdefghij";
for (unsigned u = 0; ; u++)
  cout << letters[ u % 10 ];

The modulus doesn't need to be ten. It can be anything you want, like three.

That should be enough to get you started.

Duoas 1,025 Postaholic Featured Poster

It's doing the same as your memset.

Hmm... I thought that was a C++ thing. Well, I've learned something.

Alas, sorry for the late night quick diagnosis.

Your algorithm assumes that the very first character in the string is a space. If you change your input string to char line[]=" 33333n5rr door 3333is closed . n5rrr nanana tt4tt wall t6tt6t"; you'll see it work just fine.

The other solution would be to change p2's initialization to char *p2 = record_out +1; Barring those, I'd rethink the algorithm... (which I didn't want to think about yesterday --sorry again).
:$

Duoas 1,025 Postaholic Featured Poster

Geek.

/me runs off to try out this super coolness.... :)

Duoas 1,025 Postaholic Featured Poster

This looks like homework.

If it isn't, you can use the std::sort() algorithm.

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

It is complaining because you are trying to return an array that will disappear the instant the function terminates.

I'd swear I just read/responded to this very issue not too long ago, but I can't find it.

Since you aren't using the result of ADD_STUD, just make it void and don't return anything.

If you really do want to return an array, you have to allocate it first:

int *make_ints( int count )
  {
  int *result = new int[ count ];
  for (int i = 0; i < count; i++)
    result[ i ] = count -i;  // whatever
  return result;
  }

But you must also remember to deallocate it once you are done with it.

int *foo = make_ints( 3 );
  for (int i = 0; i < 3; i++)
    cout << foo[i] << endl;
  delete [] foo;

Finally, you can avoid the grief and just use a std::vector or std::deque to do the dirty work:

std::vector<int> make_ints( int count )
  {
  std::vector<int> result;
  for (int i = 0; i < count; i++)
    result.push_back( count -i );  // the same whatever
  return result;
  }

Not only do you not have to clean up after yourself, you get other benefits:

std::vector<int> foo = make_ints( 3 );
  for (int i = 0; i < foo.size(); i++)
    cout << foo[i] << endl;
  // Hey, I don't have to delete/free/whatever 'foo'!

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

Don't worry about it. You don't want to work with a bunch of Real Programmers. Anyone dinking around with the bits of class layout in memory, or caring how it actually is layed out, is either writing a compiler or is doing a disservice to their employer.

Duoas 1,025 Postaholic Featured Poster

Me too. ;)


(I wrote this for students who couldn't write a ten-line makefile. This one is actually pretty straight-forward, but it uses a couple of GNU-specific tricks. You should see the reams of unreadable garbage that comes out of automated programs like automake and the like.)

Duoas 1,025 Postaholic Featured Poster

Don't do this: char recordd[sizeof(record)] [b]= {0}[/b]; It isn't doing what you think it is.

As another hint, you should compile using the -Wall option. I did and it told me, right off the bat without having to look at your code:

  • You are missing a header (since the compiler is assuming isdigit is type int isdigit() )
  • Both of your functions are missing return statements.
  • You have declared two variables that you don't use: o and len.

Penultimately, while the compiler doesn't complain, don't use C++ comments. (Though I like your style.)

And lastly, I regret having ever told anyone that system(PAUSE) is good even for homework assignments. Don't use it.

Here is your code cleaned up:

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

/*-------------------Function--------------------------------------------*/
void AD(char *record, char *record_out)
{
    char *p1 = record;
    char *p2 = record_out;

    while ( *p1 )
    {
        // use temp pointer to locate
        // end of digits
        char* p3 = p1;
        while( isdigit(*p3) )
            p3++;
        // is there a space following the digits ?
        if( *p3 == ' ')
            // yes, then skip the space and move on to the next char
            p1 = p3+1;
        else
        {
            // no, then was the last char put into temp buffer
            // a space
            if( *(p2-1) == ' ')
                // yes, then overwrite that space with a new character
                p2--;
            p1 = p3;
        }
        // copy all characters up to the next digit
        while(*p1 && !isdigit(*p1) ) …
Duoas 1,025 Postaholic Featured Poster

I'm back.

...and solved again.

...

Phew. It works. yeey.

Glad to have not been of help. :idea: :)

Thanks, I'm not Japanese but Dutch. Where'd you get that idea?

Dutch people say "hai"?

Duoas 1,025 Postaholic Featured Poster

How about:

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

int main()
  {
  int numbers[] = { 12, -7, 42, 9 };

  cout << "largest  = " << max_element( numbers, numbers +4 ) << endl;
  cout << "smallest = " << min_element( numbers, numbers +4 ) << endl;
  }
Duoas 1,025 Postaholic Featured Poster

R U Japanese? (osu?)

You have misunderstood the purpose of #include files.

Each separate module (.c file) should be compiled separately (into a object file: .o or .obj).
Each module should have a header file (.h file) that prototypes what can be found in the object files.

For example, suppose you have a module named "hanasu" that just prints a greeting to the console:

/* hanasu.c */

#include <stdio.h>

void hanashite( int count )
  {
  for (; count > 0; count--)
    puts( "wan wan yo!\n" );
  }

Now, you want to be able to use this procedure in your main program. To do that, the main program must know what the procedure looks like. This is where your header file comes in.

/* hanasu.h */

#ifndef HANASU_H
#define HANASU_H

void hanashite( int count );

#endif

Now you can use it in your main program:

/* woof.c */

#include "hanasu.h"

int main()
  {
  hanashite( 3 );
  return 0;
  }

To compile, make sure Code::Blocks is aware of each .c file in your project. (It has been a long time since I've used Code::Blocks, but there should be a Project menu item where you can specify which files are part of your project.)

On the command-line, you'd use GCC thus:

gcc woof.c hanasu.c -o woof

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

Well, that's all I know... sorry.

Duoas 1,025 Postaholic Featured Poster

The C++ standard does not specify layout, so the internal layout of a class or structure will vary by compiler. (Though, for most compilers the first thing is a pointer to the v-table, then the fields, so old C code that relies on struct and struct.first_member will probably compile just fine.)

As Salem indicated, it is always dangerous to assume anything about actual memory storage.

Duoas 1,025 Postaholic Featured Poster

Have you used glClear()?

Duoas 1,025 Postaholic Featured Poster

You've got it.

You are saying that you actually see the messagebox? (I didn't get that far...)

It seems my CRLF handling (*cough*) wasn't good enough (*cough*). When I wrote it I tested using a stringstream, but apparently it did something to the CRLF I didn't expect, so it appears that you'll have to open your file in binary mode after all... Sorry about that.

I'll play with fixing that, but in the meantime you'll just have to strip any '\r' off the end of the line manually:

#include <iostream>
#include <fstream>

using namespace std;
using namespace datefile;

ifstream ReadFile("C:\\Folder1\\File1.txt", ios::binary );  // Binary mode

time_t date = string_to_date( "01/03/1999" );
streampos linepos = find_date( ReadFile, date);

 if( ReadFile )
 {
      string line;
      getline( ReadFile.seekg( linepos ), line, '\r' );  // stop at CR of CRLF

      String^ FoundLine = gcnew String(line.c_str());
      MessageBox::Show(FoundLine);
 }

I'm so sorry... :$

Duoas 1,025 Postaholic Featured Poster

Try it. :)

(Its a preprocessor macro.)

Duoas 1,025 Postaholic Featured Poster

Just change CC=gcc to CC=g++ Behold, the Make Anything Makefile:

#-----------------------------------------------------------------------------
# Make Anything Makefile
#-----------------------------------------------------------------------------
# For use with GNU Make
#
# The only prerequisite to using this Makefile is that the program source
# files all reside in their own directory, with only ONE of these source
# files declaring main(). For example,
#
#   my_last_nameHW3/
#     Makefile                 <-- "make anything" makefile
#     linked_list.h
#     linked_list.cxx          <-- the file the student modifies
#     node.h
#     test_linked_list.cxx     <-- the file containing the main() function.
#
# This makefile will correctly identify the files and produce:
#
#   linked_list.o
#   test_linked_list.o
#
# and then the executable
#
#   test_linked_list*
#
# The orphan "node.h" is included in every source module's prerequisites,
# regardless of whether it is actually used by that module.
#
#-----------------------------------------------------------------------------
# When MIXING C and C++ modules, this makefile will compile the C modules
# with the C compiler, and the C++ modules with the C++ compiler. Keep that
# in mind! (Also, the linking stage will be done with the C++ compiler.)
#
#-----------------------------------------------------------------------------
# "make clean" works as usual.
# "make cleaner" works better than usual.
#
# --Michael
#

#-----------------------------------------------------------------------------
# general options
#-----------------------------------------------------------------------------
# These are the names of the C and C++ compilers to use, and options common
# to both compilers.
#
# If you want to specify an option specific to only one of the compilers,
# just place it after the compiler name. For example: …
Duoas 1,025 Postaholic Featured Poster

Your top array (the one containing arrays) should be defined something like (assuming you are storing ints): [B]int[/B][] lists[ 10 ]; // Ten arrays of variable length. Now you must decide how to know how long each array is. You could store its length as the first integer in the array. For example:

#include <stdio.h>
#include <stdlib.h>

int main()
  {
  int[] lists[ 10 ];
  int   i, j;

  int *make_int_subarray( int length );

  // Initialize
  for (i = 0; i < 10; i++)
    lists[i] = NULL;

  // Fill some of the sub-arrays
  for (i = 0; i < 6; i++)
    lists[i] = make_int_subarray( (i+1) * 2 );

  // Print the arrays
  puts( "The arrays are:" );
  for (i = 0; i < 10; i++)
    {
    for (j = 1; j < lists[i][0]; j++)
      printf( "%i ", &lists[i][j] );
    printf( "\n" );
    }

  // Free all memory
  for (i = 0; i < 10; i++)
    if (lists[i] != NULL)
      {
      free( lists[i] );
      lists[i] = NULL;
      }

  return 0;
  }

int *make_int_subarray( int length )
  {
  int i;
  // Allocate storage for the array
  int *result = (int *)malloc( (length+1) * sizeof(int) );

  // Store its length
  result[0] = length;

  // Fill it with numbers: 1, 2, 3, ...
  for (i = 1; i <= length; i++)
    result[i] = i;

  return result;
  }

Hope this helps.