Duoas 1,025 Postaholic Featured Poster

Actually it does have it backwards... foo = [B]this[/B]->foo; != [B]this[/B]->foo = foo; ?

Ancient Dragon commented: you are right, I should have seen that too +30
Duoas 1,025 Postaholic Featured Poster

Depending on how the data is packed.

If it is packed (MSB...LSB) ARGB then

int alpha = (color >> (3 * 8)) & 0xFF;
int red   = (color >> (2 * 8)) & 0xFF;
int green = (color >> (1 * 8)) & 0xFF;
int blue  = (color >> (0 * 8)) & 0xFF;

If it is packed in the Windows order: ABGR

int alpha = (color >> (3 * 8)) & 0xFF;
int blue  = (color >> (2 * 8)) & 0xFF;
int green = (color >> (1 * 8)) & 0xFF;
int red   = (color >> (0 * 8)) & 0xFF;

etc.

You can put these into a function for each component.

Or better yet, an ARGB_t class. You might find my response in this thread at cplusplus.com useful for some ideas. (It would be very simple to extend the RGB_t class to an ARGB_t or ABGR_t or whatever you need class.)

Hope this helps.

VernonDozier commented: Great link. +3
Duoas 1,025 Postaholic Featured Poster

std::sort and functors
Things like std::sort() are template functions. They don't exist until you try to use them with a specific type.

What follows is functional programming concepts.

The sort algorithm takes as a third argument a binary predicate, which is a function taking two arguments and returning true or false.

In the case of the sort algorithm, the predicate returns true if the first argument is strictly less-than the second argument. For integers, such a predicate might look like:

bool int_pred( int a, int b )
  {
  return (a < b);
  }

And you can sort a list of integers with it:

// This code assumes you compile with writable constants.
int ints[ 6 ] = { 1, -7, 54, 12, 519, 42 };
sort( ints, ints +6, int_pred );

The predicate need not be an actual function (like int_pred()). It can be a function object, or what is commonly called a functor.
An int_pred functor looks much the same as the function did:

struct int_pred2
  {
  bool operator () ( int a, int b )
    {
    return (a < b);
    }
  };

The only difference now is that the function is wrapped up into an object type (or class), with the () operator properly overloaded. You could use it normally, except that you must first instantiate an object of type int_pred2 before you can use it.

if (int_pred( 10, 20 )) cout << "yeah!\n";
if (int_pred2()( 10, …
Duoas 1,025 Postaholic Featured Poster

CLR code doesn't like it if you stick your own types into something it wants to manipulate exclusively.

Just stick the struct definition somewhere else (outside the CLR class). It won't hurt anything...

Hope this helps... (hope that works, I've never played with .NET). If worse comes to worse, you can just convert it into a regular function:

bool mysort( const std::string&a, const std:string& b )
  {
  ...
  }

and call the sort with

std::sort( myvect.begin(), myvect.end(), mysort );

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

You need to write the comparitor.

#include <sstream>
#include <string>

struct mysort
  {
  bool operator () ( const std::string& a, const std::string& b )
    {
    std::stringstream as( a );
    std::stringstream bs( b );
    double ad, bd;
    as >> ad;
    bs >> bd;
    return ad < bd;
    }
  };

Now you can use it with the sort() algorithm.

#include <algorithm>
#include <vector>

...

int main()
  {
  using namespace std;

  vector<string> v;
  v.push_back( "3.1,there" );
  v.push_back( "-0.7,hello" );
  v.push_back( "10.0,friend" );
  v.push_back( "3.2,my" );

  sort( v.begin(), v.end(), mysort() );

  for (unsigned i = 0; i < v.size(); i++)
    cout << v[ i ] << endl;

  return 0;
  }

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

> hen i remove the line 22 then i get the answer 1 when input 90

That's because on line 21 you assign the answer to x instead of ans. I'd get rid of x too...

Duoas 1,025 Postaholic Featured Poster

You know, all those little stars make my head spin. Basically what Salem wants you to do is:

1. Allocate space for all the pointers.
2. Allocate all the space for your ints all at once, in one continuous block of memory.
3. Go through an point all your pointers at the proper spots within that space.

Heh...

Duoas 1,025 Postaholic Featured Poster

That's because on line 22 you abnormally terminate the program. Don't do that.

Duoas 1,025 Postaholic Featured Poster

That's because you are actually creating two different types of structure.

In C and C++, arrays are something of a mixed bag.

When you declare [B]int[/B] a[ 10 ][ 5 ]; What is actually allocated is [B]int[/B] a[ 10 * 5 ]; And when you access: a[ 4 ][ 3 ] what that translates to is: *(a + (4 * 10) + 3) In contrast, an array of pointers to arrays is an entirely different thing: [B]int[/B] *a[ 10 ] In C and C++ a pointer can be dereferenced as if it were an array, but whereas before only a calculated offset and a single dereference was needed to access an element, now two dereferences are needed: a[ 4 ][ 3 ] is the same as: *(a[ 4 ] + 3) which is the same as: *(*(a + 4) + 3) Whew.

So to allocate a contiguous memory space you need to multiply the dimensions to get the total amount of memory, then do the offset calculations yourself

int *a = new int[ 10 * 5 ]  // or int *a = new int[ 10 ][ 5 ]

int& elt( int *a, int rows, int cols, int row, int col )
  {
  if ((row >= rows) or (col >= cols)) throw 1;
  return *(a + (row * cols) + col);
  }

elt( a, 10, 5, 4, 3 ) = 42;
cout << elt( a, 10, 5, 4, 3 );

Hope this helps.

[edit] Too slow again...

jephthah commented: instructive +3
VernonDozier commented: Thank you for the helpful posts. +3
Duoas 1,025 Postaholic Featured Poster

Casting won't change the type of thing found found in the array. It will only make the program look at it as if it were a different type -- which in this case is not the correct type.

You can either fix the original function to take the correct type, or you can fix the thing you are passing to it to be the correct type.

BTW, I presume it is a typo at the end of line 6 to i++ instead of j++ Hope this helps.

Duoas 1,025 Postaholic Featured Poster

The problem is that an array declared as: [B]int[/B] a[ 42 ][ 17 ]; is not the same as [B]int[/B] *a[ 42 ]; The first is a 2D array of 714 (42 x 17) ints.
The second is a 1D array of 42 pointers to int.

The c_function() is looking for something like the second, but you are trying to give it something like the first.

[edit] It is a vagary of the C language that lets you treat pointers like arrays, so however you define it, you can reference a specific int as: a[ 10 ][ 4 ] For the first type, it is just a simple multiplication and one dereference to index the element: *(a + (10 * 42) + 4) For the second type, it is two dereferences: *(*(a + 10) + 4) Hope this helps.

Duoas 1,025 Postaholic Featured Poster

Good job!

BTW, what compiler are you using? I had to pull out my old TP4 to compile it...

Duoas 1,025 Postaholic Featured Poster

I'm sorry, but I've already given you the answer without actually writing code. You'll have to think about it yourself now...

Good luck.

Duoas 1,025 Postaholic Featured Poster

Your loop encompasses both the menu and the selector, as:

do {
  display_menu();
  select_option();
while (!done);

So if the option is bad, the menu gets displayed again anyway.

What you'd probably like instead is something that catches itself. You can do it several ways, but another loop will probably do just fine.

do {
  display_menu();
  do {
    select_option();
  while (invalid_option);
while (!done)

Hope this helps.

Run.[it] commented: Thanks again mate! +1
Duoas 1,025 Postaholic Featured Poster

Forget the 4 digits thing. You are trying to skip a step. (Though you may not realize it...)

Just take a single digit at a time. For binary, it should be a zero or a one.

i, n, foo: integer;
...
result := 0;
for i := 1 to length( s ) do
  begin
  // validate digit is a binary digit
  if not (s[i] in ['0','1'])
    then complain_that_its_not_a_binary_number;
  // convert that digit into a number
  val( s[i], n, foo );
  // power up and add
  result := result * 2;
  result := result + n;
  end;

This is the exact same thing you did before with the octal: only three things have changed:
line 7: the set of valid digits have changed
line 10: ok, well that hasn't changed...
line 12: the radix is 2 instead of 8

You'll have to watch how you translate individual digits from hexadecimal. I suggest using upcase, pos, and a string that looks like this: '0123456789ABCDEF' Hope this helps.

Duoas 1,025 Postaholic Featured Poster

You've already got code that converts octal to a number (which you call OctToDec).

Remember, "octal", "decimal", etc. --these are not numbers. They are strings. Only people read and write strings.

A number is an integer or a real or some other scalar type. Computers understand numbers, not strings.

So conversion from, say, binary to octal is a two-step process.

1. Convert your binary (string) in to a number (integer).
2. Convert your number (integer) to an octal (string).

You'll need two procedures: one for each step.

Remember, you've already done step 1 once (with an octal string to an integer). You can do it the same way for binary or decimal or hexadecimal --the only difference between them is the radix: 2 (binary), 8 (octal), 10 (decimal), or 16 (hexadecimal).
For your OctToDec routine (listed here) you've got the radix (the number 8) on line 24, and the set of valid digits on line 16. I don't know how you fixed line 23 to convert the digit (a character) to a number (integer), but you'll have to do the same sort of thing for every radix. Except for those three lines, everything else is the same.

To go the other way the math is just reversed. Instead of building up a number by tearing down a string, you'll build up a string by tearing down a number.

Think about it a bit and give it a go. …

Duoas 1,025 Postaholic Featured Poster

Yes, OK. Your routine should terminate when you hit one, not -1. (You've got it right for the last three clauses of your code -- the stuff handling the positive numbers.) The trick is what happens when things go negative.

It might help to visualize what is going on a couple of times.
The routine is (should be) defined to recurse as follows (what you have for positive numbers):

(mult a b) = (+ a (mult a (- b 1)))
(mult a 1) = a
(mult a 0) = 0

So for an example:

(mult 2 5)
= (+ 2 (mult 2 4))
= (+ 2 (+ 2 (mult 2 3)))
= (+ 2 (+ 2 (+ 2 (mult 2 2))))
= (+ 2 (+ 2 (+ 2 (+ 2 (mult 2 1)))))
= (+ 2 (+ 2 (+ 2 (+ 2 2))))
= (+ 2 (+ 2 (+ 2 4)))
= (+ 2 (+ 2 6))
= (+ 2 8)
= 10

And another:

(mult -2 5)
= (+ -2 (mult -2 4))
= (+ -2 (+ -2 (mult -2 3)))
= (+ -2 (+ -2 (+ -2 (mult -2 2))))
= (+ -2 (+ -2 (+ -2 (+ -2 (mult -2 1)))))
= (+ -2 (+ -2 (+ -2 (+ -2 -2))))
= (+ -2 (+ -2 (+ -2 -4)))
= (+ -2 (+ -2 -6))
= (+ -2 -8)
= -10

So far, so good. But what if b

Gagless commented: Great. Very insightful. +1
Duoas 1,025 Postaholic Featured Poster

Heh heh heh... Glad you got it working.

Now i need to change color when im editing manualy the StringGrid, how can i do that?

That, my friend, is a whole new can of beans. A really big, really deep one. Essentially you have to write your own cell editor. It isn't particularly difficult, just involved. Can you live with the way it works now? Or do you want to continue?

Duoas 1,025 Postaholic Featured Poster

I apologize but I'm not understanding, wouldn't this produce a positive result? negative by negative = positive.

I think you need to reconsider you math.

In particular, remember the definition of multiplication: [b]a multiplied by b is a added to itself b times[/b] Now we'll have to use the associative property and distributive property (of multiplication over addition). In the following, [b]a[/b][I]n[/I] is to be understood as the nth term of a. A couple steps are skipped for brevity. -[B]b[/B] x [B]a[/B] = (-1 x [B]b[/B]) x [B]a[/B] = -1 x ([B]b[/B] x [B]a[/B]) = -1 x ([B]a[/B][I]1[/I] + [B]a[/B][I]2[/I] + ... + [B]a[/B][I](b-1)[/I] + [B]a[/B][I]b[/I]) = (-1 x [B]a[/B][I]1[/I]) + (-1 x [B]a[/B][I]2[/I]) + ... + (-1 x [B]a[/B][I](b-1)[/I]) + (-1 x [B]a[/B][I]b[/I]) = -[B]a[/B][I]1[/I] - [B]a[/B][I]2[/I] + ... - [B]a[/B][I](b-1)[/I] - [B]a[/B][I]b[/I] So, if we were to say b is 5 (as in, we are multiplying a by -2), we can substitute to get: -[B]a[/B] -[B]a[/B] -[B]a[/B] -[B]a[/B] -[B]a[/B] Suppose a is 2: -2 -2 -2 -2 -2 Suppose a is -2: -(-2) -(-2) -(-2) -(-2) -(-2) = 2 + 2 + 2 + 2 + 2

And I'm still getting a stack overflow error. The integers I use for testing are 2 and -5.

OK, that is odd. Let's see your code.

Duoas 1,025 Postaholic Featured Poster

You are correct. The process file table and the current working directory are not modified by exec(), so the new executable inherits it all.

Duoas 1,025 Postaholic Featured Poster

GCC has very limited support for tail recursion. The C++ standard does not require it, so if you want those kinds of optimizations you'll have to read your compiler's documentation on how to do it.

Iterative languages typically do not support tail recursion anyway... But that is usually a moot point since iterative and functional languages target a different application domain.

:-/ :)

Duoas 1,025 Postaholic Featured Poster

You're getting a stack overflow on windows? Are you on Windows 98 or something?

In any case, make sure you don't multiply too large of a number. It costs a lot more than you think in stack space to call a function, so it adds up fast.

The reason you are getting a positive number is that you only subtract the first addend, and add the remainder. You have to subtract all of them.

The best way to do that is this:

if (Multiplier < 0)
  {
  Number = -Number;
  Multiplier = -Multiplier;
  }

Now every time you add Number, you are adding a negative number; i.e. subtracting. If both terms were negative, you'll also properly get a positive result.

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

Unfortunately the standard decided that such lowly things as file descriptors are too device-dependent, so there is no standard way to do that.

That said, many compiler systems provide a way to create an iostream connected to a file descriptor. Check your compiler documentation.

If you are up to it, a better solution would be to derive an iostream class that does it. Since this is a common problem, solutions by other people exist.
http://www.josuttis.com/cppcode/fdstream.hpp.html (very compact and simple)
http://www.boost.org/doc/libs/1_35_0/libs/iostreams/doc/index.html (very powerful)

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

IMO, interfacing with the user is one of those things that needs to be absolutely bullet-proof.

There are two things to keep in mind here:

1. How does the user expect to interact with your program.
2. How does your program react to insane responses.

Answer 1: For console applications, users expect to have to press ENTER after every input. Just expect it.

Answer 2: Don't crash or do something regrettable.

For example, with just cin.get() (a simple solution for homework, etc), what if the user presses A, N, Y. (That is not a joke. It actually happens, and has had serious consequences!)

So, for this kind of thing, when you are writing production code I always advocate the ignore() method. There is an example of it in the first link VernonDozier gave you.

Keep in mind that if you have been using cin >> foo; up till then, you will have to first empty the input with an additional ignore()...

Hope this helps.

VernonDozier commented: Good post. +3
Duoas 1,025 Postaholic Featured Poster

Argh. You made me go and do this myself. I forgot how primitive a TStringGrid is... It derives from TCustomGrid but hides its DrawCell method...

Alas. I also forgot to wrap the method body in an appropriate with statement above. (All this stuff is in the documentation.)

procedure Form1.sGridDrawCell( ... );
  ...
  begin
  with Sender as TStringGrid do
    begin
    savefg := Font.Color;
    savebg := Canvas.Brush.Color;

    if not (gdFixed in State)
      then ...

    // Fill the background color of the cell
    Canvas.FillRect( Rect );

    // Draw the text with the desired foreground color
    Canvas.TextRect( Rect, Rect.Left +2, Rect.Top +2, Cell[ ACol, ARow ] );

    ...
    end
  end;

When I messed with this before (Long Ago), I wrote my own TGrid descendant, so DrawCell was available to me. Sorry I forgot about that.

Good luck.

Duoas 1,025 Postaholic Featured Poster

1. Yep. Exactly. Sender should be sGrid.

2. Oops! It should be sGrid.DrawCell( ACol, ARow, Rect, State ); I just typed this stuff in off the top of my head...

You can resolve things like this by placing the cursor over the name "DrawCell" and pressing F1. The online help will give you choices of TCustomGrid objects to choose from. This means that DrawCell is a method of a TCustomGrid (or descendant), not TForm.

3. However you change the cell, you must somewhere remember that the cell has been changed.
The TStringGrid.Objects[] property allows you to attach arbitrary data to each cell. You can use a simple class to keep information about the change state of the cell:

type
  TCellDataModified = class end;

Then, when you modify a cell, tag it by the presence of a modified class:

with sGrid do
  begin
  Cells[ 1, 0 ] := x;
  if not Assigned( Objects[ 1, 0 ] )
    then Objects[ 1, 0 ] := TCellDataModified.Create
  end;

And finally, inside the IsHighlightMyCell function, you can simply return whether or not the cell has an attached TCellDataModified object:

function TForm1.IsHighlightMyCell( Sender: TStringGrid; row, col: longint ): boolean;
  begin
  result := Assigned( Sender.Objects[ col, row ] )
  end;

You will have to remember to free all objects you create at some point (like if you delete a row or column, or when you delete the whole table).

// delete entire table
with sGrid do
  for row := 0 to RowCount -1 …
Duoas 1,025 Postaholic Featured Poster

No, I mean convert bin (a string) to integer. Then convert the integer to hex (another string).

I hope that makes more sense.

Duoas 1,025 Postaholic Featured Poster

10110011101 is binary. You don't have to break it into anything. Just convert it to a number.

Once you get your number from the first step, convert it into hexadecimal: 59D.

Remember, the difference between digit powers is the radix.
Remember, binary and decimal and octal and whatever is text, writing, strings, human readable stuff. They aren't numbers.

Convert a string to a number using one radix.
Convert the number to a string using another radix.

Duoas 1,025 Postaholic Featured Poster

In your OnDrawCell event you need to choose your color based on whatever criteria you are interested in. The criteria may apply to more than one cell, even.

procedure TForm1.sGridDrawCell(
  Sender:     TObject;
  ACol, ARow: Longint;
  Rect:       TRect;
  State:      TGridDrawState
  );
  var
    savefg: TColor;
    savebg: TColor;
  begin
  // Save the current colors
  savefg := Font.Color;
  savebg := Canvas.Brush.Color;

  if not (gdFixed in State)
  and IsHighlightMyCell( Sender, ARow, ACol )  // note 1
    then if (gdSelected in State)
           then begin
                // Something really bright for highlighted special cells
                Font.Color         := clYellow;
                Canvas.Brush.Color := clRed
                end
           else begin
                // Something not quite so bright for normal special cells
                Font.Color         := clLtGray;
                Canvas.Brush.Color := clMaroon
                end;

  // All I wanted is to change colors,
  // so we'll let the string grid draw itself.
  DrawCell( Sender, ACol, ARow, Rect, State );

  // Restore the original colors
  Canvas.Brush.Color := savebg;
  Font.Color         := savefg
  end;

The line labeled "note 1" is what you are interested in. You should have a function as: [B]function[/B] TForm1.IsHighlightMyCell( Sender: [B]TStringGrid[/B]; row, col: [B]longint[/B] ): [B]boolean[/B]; which indicates whether or not the indicated cell needs to be highlighted. You can choose any criteria as to whether the cell is highlighted or not.

For example, you could have the function body as: result := (Sender.Cells[ row, col ] = 'Hello'); This would be true for every cell with the text "Hello".

You could highlight the third column: result := (col = 2); Whatever you want.

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

What?

Duoas 1,025 Postaholic Featured Poster

I recommend writing yourself a little procedure to do it

You'll have to write that function yourself.

For hexadecimal, remember that the values of the digits are:
digits: values
0..9: 0..9
A..F: 10..15

So the DigitToInt( 'C' ) should return the value 12.
Good luck.

Duoas 1,025 Postaholic Featured Poster

Remember, a char is a different type than an integer. You cannot add or multiply characters.

Also remember, the point is that the digits 0, 1, 2, 3, ... are representations of numbers, not numbers themselves.

Line 23: Result:=result+[b]octal[len][/b]*base; You'll have to convert the bolded part from a character into a number. I recommend writing yourself a little procedure to do it, so you can change the code to something like: Result:=result+[b]DigitToInt(octal[len])[/b]*base; Very good job on the procedure, by the way.

You don't actually need the 'counter' variable. Just use [b]downto[/b] 1 .

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

Link.

Enjoy!

Duoas 1,025 Postaholic Featured Poster

You are screwing-up your gcount() by using ignore(). Get the count first, then ignore.

Hope this helps.

Run.[it] commented: Your da man! Safe +1
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

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

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

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

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

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

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

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

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

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

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... :$