Duoas 1,025 Postaholic Featured Poster

The TMediaPlayer component should be able to play with any codec installed on your computer.

Can you play the file normally using Windows Media Player from Explorer?

Duoas 1,025 Postaholic Featured Poster

His question is why the rewritten stuff on Windows 7 works so much faster than what he had been using.

@OP:
You state that you are using CopyFileEx() (a Win API function) on Unix systems and it is going slow. Assuming your original code does not have any hooks on the call, it is at least going through an emulator (Wine, presumably), not to mention the overhead of going over network protocols.

You then state that you are using SHFileOperation() to have the Windows Shell perform the same function call and it is running faster, but on a native Windows 7 machine.

Without seeing your code for both the original and the rewritten stuff, I can only assume that playing with the OS emulator is costing you.

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

There is no exhaustive list, because each compiler system + OS has their own.
There are common, standard ones, though.
Here's the GNU CPP's documentation.

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

Why are you subtracting 1 on line 11?

Duoas 1,025 Postaholic Featured Poster

Plenty of people still program with ancient, pre-standard compilers, particularly in places like India.

Also, there does exist the WinBGIm port for MinGW, so old BGI code certainly can and does compile with modern GCC.

Alas, I am currently reinstalling my compiler (I managed to hose it with an 'automatic update' process -- never trust those), so I cannot compile and test your code right now. That said, I don't see anything obviously wrong with it.

What exactly is the error you are getting when you run it?

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

Quicksort over a non-random access sequence is, I admit, tricky.

Duoas 1,025 Postaholic Featured Poster

Why is everyone trying to quicksort a linked list?

Duoas 1,025 Postaholic Featured Poster

I hesitate to link to another site for your answer, but your question about how to use qsort() is entirely answered in the FAQ here. It explains how qsort() works and gives an example of randomizing data with it. That comparison function is the key to making it work.

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

You are not being specific -- your question is very vague.

So far as I can tell, you want to display 1000 things in 20 slots, but without any way of recycling the 20 slots.

Duoas 1,025 Postaholic Featured Poster

I wish I could say. Richedit does have some random issues.

1) Make sure you are linking to the most current RichEdit DLL (4.1).
2) Make sure your window with the RichEdit control is not doublebuffered.
3) Make sure your manifest is correct.

I assume you are using the RichEdit's scrollbar and not linking to one of your own?

Duoas 1,025 Postaholic Featured Poster

Is there something left out about the format of the data you are searching?

There is no way to search random data faster than O(n).
However, if your data were sorted then you could search it in O(log n).

Also, every time you add extra code to do something the loop already does, you increase the amount of time it takes to work.

What is this for? An algorithms class? Or basic CS?

Duoas 1,025 Postaholic Featured Poster

I'm confused. Are you talking about a circular buffer?

Duoas 1,025 Postaholic Featured Poster

stty is not the best option for this.

You should first look to see if the environment variable $COLUMNS exists. It is most likely to be correct.

Failing that, use the command tput cols to query the terminal size.

If you really want to do it properly though you'll have to use ioctl() with TIOCGWINSZ.

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

You go try to use std::sort with std::list first.

And this is a very obvious homework problem, either from an actual school or from a book.

Duoas 1,025 Postaholic Featured Poster

Neither std::sort() nor quicksort are appropriate for sorting a linked list.

Further, homeworks typically expect you to do the sorting yourself.

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

That code is wrong in a number of subtle and dangerous ways. But what it is trying to do is write the binary value of a 'PasswordGenerator' object to file.

Any object you wish to write should have a function to explicitly convert it to either text or binary. If you google around "serialization" you'll find all kinds of stuff, but it might be overload.

Here's a simple example to get you going:

// Here's our fictional object type.
// It contains an integer (very easy to write to file)
// and a string (not so easy).
class Quux
{
  private:
    int         x;
    std::string s;

  public:
    Quux( int x, const std::string& s ): x(x), s(s) { }

  // The stream insertion operator must be a friend
  friend std::ostream& operator << ( std::ostream&, const Quux& );

  // As must be the stream extraction if you intend to read a Quux from stream
  friend std::istream& operator >> ( std::istream&, Quux& );
};

// Here's a function to turn a string like [Hello "Bill"] into [Hello \"Bill\"]
std::string quote( const std::string& s )
{
  std::string result;
  for (char c: s)
    switch (c)
    {
      case '\\': s += "\\\\";
      case '\"': s += "\\"";
      // You can add any other transformation you like here. For example, 
      // you can turn newlines into [\n] with  case '\n': s += "\\n";
      default:   s += c;
    }
  return result;
}

// Here's the stream insertion operator function, which writes a string that looks like
//
// …
Duoas 1,025 Postaholic Featured Poster

Using a library and decoding an image yourself are two totally different things.

The OP cannot change his compiler's environment, but there is never any restriction on the files you can create for a single-user directory (outside of diskspace, of course).

Using CImg would work fine.

(I know this is old. Has OP solved his problem?)

Duoas 1,025 Postaholic Featured Poster

What you've got seems to introduce but not use 't', and has a bug on line 16 (when temp->next is NULL).

Also, you are endeavoring to do two things at once: sort and display. Don't do that. Put the sort stuff in its own function.

Sorting is not particularly easy, but the simplest sort you might employ over a singly-linked list is called insertion sort.

You'll need two lists -- an empty one (new_head) and the one you wish to sort (head).

While there are elements in head pop off the first one.

Find where it belongs in new_head and insert it there. (You should have a function to insert a node in your list, right?)

When you are done, just return the new_head list from the function.

(And yes, this is an N-squared algorithm, but for your homework lists you shouldn't notice.)

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

Hey all.

I'm always frustrated that I cannot seem to find a reference that shows when a feature was introduced in Delphi.

For example, to use ErrOutput, I have to manually create that value in D5. But what about D6? or D7?

Does such a reference exist?

Duoas 1,025 Postaholic Featured Poster

Apple is putting a lot of effort into LLVM. Unfortunately, the LLVM debugger doesn't work with FPC (yet, AFAIK).

You'll either have to get an old copy of the GDB or install an older version of X-Code (you can do this side-by-side with your current version).

Alas, I don't have access to a Mac and I don't know any better than this. I just noticed that no one has answered your question...

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

It is not egotistic to simply respond to having one's very simple code roundly abused. The function has the performance and memory characteristics desired when I wrote it. It has no leaks. It does what it is supposed to do. And it isn't filled with convoluted, non-standard stuff.

I've responded to the syntax error you have actually shown me by correcting it, but you have yet to respond by showing exactly how my function has a "logic error" or what all these unnamed "bug"s are. Instead you have resorted to ad homenim by personally belittling my understanding, experience, imagination, and behavior.

Bye.

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

Your program needs to take the file name as argument. Example program:

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

int main( int argc, char** argv )
  {
  // Make sure the program has at least two arguments:
  //   1: the program's executable path
  //   2: the file name passed to your program
  if (argc != 2)
    return 1;

  // Open the argument file
  ifstream f( argv[ 1 ] );

  // If the file could not be opened, we're done.
  if (!f)
    return 1;

  // This example program just counts the number of lines in the file...
  size_t num_lines = 1;
  while (f.ignore( numeric_limits <streamsize> ::max(), '\n' ))
    ++num_lines;

  f.close();

  // ...and displays the count to the user
  cout << "The file \"" << argv[ 1 ] << "\" contains " << num_lines << " lines.\n";

  // Keep the console open long enough for the user to see the result.
  cout << "Press ENTER to quit.";
  cin.ignore( numeric_limits <streamsize> ::max(), '\n' );

  return 0;
  }

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

It should also be noted, in addition to StuXYZ's excellent comments, that you should get an entire Student before adding a copy of it to the vector.

Your choice of variable names is pretty good, actually, but I will nit-pick about the vector name: "sNames" -- first, it isn't a vector of student names, it is a vector of student data, which includes the name. A good name for a collection of Student is "students".

So, remember, the order to do things is:

  1. Get all the information about a student into a single Student object.
  2. Use push_back() to append a copy of that Student object to the vector of Students.
  3. Repeat.

Also, I notice you have variables starting with the prefix "temp". You never use them, so get rid of them. (Delete lines 21 and 22.)

Remember, a Student is not just a name. It is a collection of information about one particular student: his first name, last name, and all his grades.

// Here is the list of students we wish to populate.
vector<Student> students;

...

// This loop gets 'numStudents' students from the user.
for (int i = 0; i < numStudents; i++) {

    // This is the temporary variable we'll use to hold information
    // about a single student as we get it from the user.
    Student student;

    // Now, gather the individual pieces until we have them all.

    cout << "Enter the first name for student #" << (i …
Duoas 1,025 Postaholic Featured Poster

That's because the answer given you is not correct -- the very first form auto-created in your DPR is the application's main form -- which is not what you want.

You still need to edit the DPR, but in a different way. If you google around "delphi spash screen" you'll get some good hits, like this one:

http://www.delphi-central.com/splash.aspx

Good luck!

Duoas 1,025 Postaholic Featured Poster

I'm actually surprised you posted something like this, as it is a dangerous function -- especially for newbies who don't really know what the consequences of using it are.

Typically, a GUI should not be Sleeping/Delaying at all. If you must pause for some reason, use one of the Win32 Wait functions.

The purpose of a Sleep/Delay function is to block execution of the current thread for some amount of time.

If what you want to do, instead, is to schedule something to happen in the future, use a TTimer object, which properly integrates into the main event loop.

(What the code above does is create a potential nested event loop nightmare.)


Example of waiting for a key press:

program pak;
{$apptype console}
uses SysUtils, Windows;

function IsKeyPressed( ms: DWORD = INFINITE ): boolean;
  begin
  result := WaitForSingleObject( GetStdHandle( STD_INPUT_HANDLE ), ms ) = WAIT_OBJECT_0
  end;

begin
WriteLn( 'Press any key to wake me up.' );

repeat Write( 'Zzzzz' )
until IsKeyPressed( 500 );

WriteLn;
WriteLn( 'Hey, wha''d ''jou go ''n do that for?' )
end.

If you are doing something that is simply a lengthy process, either farm off to another thread (preferred) or simply check now and then that there is no waiting input using either a substitute Window Procedure or a global application state (such as disabling controls that should not be used while processing your long request).

Duoas 1,025 Postaholic Featured Poster

Require your users to use specific input formats. Something like "M 36 John Doe Mary F 45" is nonsense at best and malformed otherwise. If you have two people then that should assume two inputs. If your user puts nonsense into the program, tell him!

So, You can assume one of the following by specifically restricting your user to:
Given Name, Surname, Age, and Sex, where the name is in one of the standard forms: "First Last" or "Last, First".

M 36 John Doe    M 36 Doe, John
36 M John Doe    36 M Doe, John
M John Doe 36    M Doe, John 36
36 John Doe M    36 Doe, John M
John Doe 36 M    Doe, John 36 M
John Doe M 36    Doe, John M 36

You can easily determine which is which by examining the type of the string.
If you have "M" or "F" or "Male" or "Female" or "m" or "f" or "male" or "female" or "MALE" or some other variation, then you know it represents the sex. If you have a number than it should represent the age. Otherwise it must be a name: If it ends with a comma (,) then it represents the last name -- otherwise it is given name. The next name item is either the surname or the given name, depending on what the first encountered name is.

There is a potential issue, mind you. Not all people have such simple names. Something like …

Duoas 1,025 Postaholic Featured Poster

The original problem is that with the constructor and destructor source missing from the class prototype, and commented out in the implementation, there was no way for your line 10 to work: Item test; .

Not so. If you don't provide a ctor, the compiler is required to create a default one for you.

Is this the correct way to use an accessor (getter) function?

Yes. However, your getter methods should be const: int getArrival() const;

I am concerned that the way I have declared "arrival" in the Item.cpp file makes it a public variable.

It doesn't matter because you shouldn't be doing this. Line 4 of Item.cpp creates a different variable than the one on line 13 of Item.h. Get rid of that line 4 and you should be fine.


A common thing to do is to have the both the ctor and the assignment operator call a common setter method. For example:

Item(int x = 0, string y = string()) { makeItem(x, y); }

BTW, "x" and "y" are not very descriptive names. You should name them like you originally had.

Also, your makeItem() should take a const reference string: void makeItem(int arrival_time, const string& destination_name) Hope this helps.

Duoas 1,025 Postaholic Featured Poster

Yes, use an istringstream.

string s = "John Doe M 36";
istringstream ss( s );

string name, given_name, surname;
char sex;
unsigned age;

ss >> given_name >> surname >> sex >> age;
name = given_name + " " + surname;

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

IIRC, it worked just fine. You aren't seeing output because of the way Turbo C/C++ initializes the console output.

The problem is that you are doing something wrong. Are you trying to get a directory listing? Or just show it to the user?

Duoas 1,025 Postaholic Featured Poster

Some repairs.

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

int main()
{
  int i ;
  i=system("dir");
  printf("%d",i);
  getchar();
  return 0;
}

This is correct.

@nezachem
system() expects either an executable or a shell builtin.

The system() function can fail for a number of reasons. Be sure to read the man page (which is correct for DOS also).

You can see if the shell is available by calling i=system(NULL); . If it is available, check to make sure your shell is cmd.exe or command.com.

All that said, I'm not sure this is what you really want. Are you trying to get the names of files in the current working directory? You may want to google around the "readdir" family of functions -- they are fairly portable even if you have to #include different headers on DOS/Windows.

Hope this helps.

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

:-@
Whoops!

Duoas 1,025 Postaholic Featured Poster

Hmm, without knowing anything at all about the OP's original purpose, this thread has become a hate-war over clearing the screen.

It is not uncommon for old DOS programs to assume complete control of the console -- particularly in business environments. Catagorically stating that it is always/never acceptable to do something is beyond anyone's qualifications.

"Porting" from DOS is not something that is usually done for trivial CS 101-type and nicely-behaved streams-type programs. The OP seems interested in correctly porting all the original behaviors of the program... which include taking over the console. I would otherwise agree with Narue's curt remark -- you probably don't need it. Well-behaved streams applications don't muck with the user's TTY.


On *nix systems, you will have to either emit the correct terminal escape sequences yourself or use NCurses. (There are other ways to do this, but they are not Correct -- they either introduce security holes in your application or will break on systems other than your development machine[s].)

To properly emit the "clear" sequence yourself (in *nix), use the following very simple snippet:

#include <unistd.h>
#include <term.h>

void ClearScreen()
  {
  if (!cur_term)
    {
    int result;
    setupterm( NULL, STDOUT_FILENO, &result );
    if (result <= 0) return;
    }

  putp( tigetstr( "clear" ) );
  }

You will have to link with the appropriate library (-lcurses, -lncurses, -lterminfo, or something odd on your system -- SunOS is particularly obnoxious about linking to the correct library).

By "very simple" I …

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

I presume you are getting your error when lines 4 through 12 of Item.cpp are uncommented?

You cannot just add methods to a class. You need to prototype them along with the class.

class Item
{
public:
	Item();
	~Item();
	void makeItem(int arrival, string dest);


private:
	int arrivalTime;
	string destination;
};

BTW, you are doing a couple of unkosher and dangerous things.

Don't using namespace [i]anything[/i] in header files. It isn't up to you what to stick in the user's global namespace. (Even if you are your own user.)

Stick the appropriate #include directives in the same header file as needed. For example, your "Item.h" file should look like:

#pragma once
#ifndef ITEM_H
#define ITEM_H

#include <string>

class Item
{
...
};

#endif

I won't bug you here about namespaces, but you should have your stuff wrapped in a namespace also...

You shouldn't have files lying around just to #include all kinds of other files.

Finally, your makeItem() method seems to be doing the job of the constructor. Why not just have the constructor do it?

#include <iostream>
#include "Item.h"
using namespace std;

int main()
{
	cout << "beginning" << endl;

	Item item(3, "Dallas");

	cout << "end" << endl;

	return 0;
}

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

Your professor has actually given you a complete solution -- but his pseudocode is a bit off.

Your function should take only one argument: v - the value to convert to base 3.

Everywhere you see "b" in his pseudocode you should replace that with "3" (because "b" is the base -- your base is 3). (You could, if you desire, add a second argument to the function: b, and use that as the base, then call the function with a base of 3. It is trivial to make the function work either way.)

Inside the function, the first thing you should do (as you have) is calculate k. You have used the second form the professor gave you, since there isn't any log3() function in the standard library. Remember that the logarithm to any arbitrary base "b" can be calculated by dividing the logarithms using another base (for example, base 10) as:
{\bf log}_{3}( v ) = \frac{{\bf log}_{10}( v )}{{\bf log}_{10}( 3 )}

The number k represents the number of digits in the output. Your professor's algorithm uses it to select the bits out of the argument v that are to be printed - most significant to least significant. Most numbers have more than one digit, so you will need to loop through them:

for (; k != 0; k--)

(His pseudocode was not very careful to indicate that there is a loop in there... but if you think about it you …

Duoas 1,025 Postaholic Featured Poster

A case statement only works on cardinal values (numbers), but you can perform a simple lookup to convert strings into an index into the list. Here's a little unit I wrote some years ago to do just that.

unit uCaseStringOf;
{
  Use strings in case statements
  Copyright (c) 2006 Michael Thomas Greer

  Boost Software License - Version 1.0 - August 17th, 2003

  Permission is hereby granted, free of charge, to any person or organization
  obtaining a copy of the software and accompanying documentation covered by
  this license (the "Software") to use, reproduce, display, distribute,
  execute, and transmit the Software, and to prepare derivative works of the
  Software, and to permit third-parties to whom the Software is furnished to
  do so, all subject to the following:

  The copyright notices in the Software and this entire statement, including
  the above license grant, this restriction and the following disclaimer,
  must be included in all copies of the Software, in whole or in part, and
  all derivative works of the Software, unless such copies or derivative
  works are solely in the form of machine-executable object code generated by
  a source language processor.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
  SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
  FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
  ARISING FROM, OUT OF OR …
Duoas 1,025 Postaholic Featured Poster

Listen to Narue. You need a bignum library. If you must fix it to exactly 20 bytes worth of data, then you can write your own simple class, or you can google around it to find some that others have written. The GMP is pretty much industry standard. There are others also, like TTMath.

Good luck!

Duoas 1,025 Postaholic Featured Poster

What version of Delphi/Object Pascal are you using and with what compiler flags/directives?

Duoas 1,025 Postaholic Featured Poster

Why not just use a free tool someone already wrote that does exactly what you want, like Irfanview?

Duoas 1,025 Postaholic Featured Poster

The Wikipedia article explains it pretty well.

The essential idea is that your application's parts should not need to know too much about each other.

For example, let's consider a simple text editor.

The "model" represents the textual data and all the stuff you can do to it, like load and save to file, search it and replace text, add and delete text, etc.

The "view" is responsible for displaying the text to the user and the UI elements that the user manipulates to modify it.

The "controller" manages these two things. For example, if the view signals that the user wishes to save (because he pressed Ctrl+S), the controller will do things like check to see if the document needs saving, whether the user needs to be asked for a filename, etc, before instructing the model to save, and afterward reporting any potential failure.

Typically an application will have more than one view (a text editor has other GUI elements besides the text widget, like menus, etc). Often the view and controller are treated as the same thing as well... It is also possible for the view to directly manipulate the model as well. (For example, pressing the Enter key when the text widget has focus doesn't necessarily involve controller action.)

Ideally, this can all be done in such a way as to make the exact model or view changeable to a different one. (For example, you could swap the …

Duoas 1,025 Postaholic Featured Poster

You want to do something non-trivial.

Why not just use Irfanview?

Duoas 1,025 Postaholic Featured Poster

Remember, you are dealing with strings, not numbers.

The textual representation of a number is what you are interested in -- that is, what characters are valid in the string version of a number?

Duoas 1,025 Postaholic Featured Poster

Yes, you need to toggle to columnar mode. You'll have to poke around your keybindings to figure out how to do it. Using the "Classic" keybindings (the modified WordStar 3 ones) you can toggle using ^O^C (columnar) and ^O^K (normal block).

I use D5 all the time -- I haven't verified that more modern versions of the IDE support this.

Duoas 1,025 Postaholic Featured Poster

Is your program to assume that input values take the most restricted radix possible?
(That is, given an input of "24" is it to assume octal?)

Keep in mind that any string containing only the characters '0' and '1' is binary; any string containing only the characters '0'..'7' is octal; etc.

This is a string-parsing homework, not a number-parsing homework, so your inputs should be using getline().

int nbin = 0;
int noct = 0;
int ndec = 0;
int nhex = 0;
string s;

while (true)
  {
  getline( cin s );

  // identify the type of number in 's'
  if (s is hexadecimal) nhex++;
  else if (s is decimal) ndec++;
  else if (s is octal) noct++;
  else if (s is binary) nbin++;
  // if it is not a valid number we are done
  else break;
  }

You might want to make yourself a useful function to check whether or not a number is hexadecimal, decimal, octal, etc.

Also, remember that order matters... unless there is some known way to distinguish radices (such as the way C++ asks for "0x92" to mean hex instead of decimal).

Good luck!

Duoas 1,025 Postaholic Featured Poster

You are trying to do too much work, especially for a large dataset.

If you were to look at the list of hits on a piece of paper, how would you find the last one for each event? Yes, you would find the words "end of event" and look at the last non-blank line above that.

The algorithm should do exactly the same thing -- just look for the words "end of event" and then print the information on the last non-blank line. This will, of course, require you to remember the last non-blank line read before the line starting with the words "end of event".

Keep in mind that there is no point in parsing information about the hit until you have the line containing that information.

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

inline string& trim( string& s )
  {
  s.erase(    s.find_last_not_of ( " \f\n\r\t\v" ) + 1 );
  s.erase( 0, s.find_first_not_of( " \f\n\r\t\v" )     );
  return s;
  }

int main()
  {
  string last_line, curr_line;

  while (getline( cin, curr_line ))
    {
    // Ignore empty lines
    if (trim( curr_line ).empty()) continue;

    // If we have found the end of an event...
    if (curr_line.find( "end of event" ) == 0)
      {
      // Scan the X,Y,Z hit information from the last non-blank line
      istringstream ss( last_line );
      string hits, varname, equalsign;
      double x = 0.0, y = 0.0, z = 0.0;
      ss >> hits
         >> varname >> equalsign >> x
         >> varname >> equalsign >> …