Murtan 317

What part have you written and/or what specific question do you have?

  • Did you get the binary file open?
  • Did you fill the vector from the file?
  • Did you find the start point of the string?
  • Were you able to append characters to your string from the vector?
  • Did you find the 'NULL' in the vector to know that you're done filling the string?
  • Did you successfully call fopen?
  • Did you successfully read the data with scanf?

We generally will not write your program for you, but will help when you show you're trying.

Murtan 317

Not to be rude about it, but why do you care if the user entered '-verbose' or '--verbose'?

If they both make the output verbose, why should they care?

Murtan 317

So your current data set is about 25 players with 20 statistics each?

Do you anticipate the number of players or the number of statistics to grow?

How critical is it that updates to the data be committed to disk immediately? (How bad would it be to 'lose' one or more updates?)

With your current data size, you could have an application that read the data, perform one or more updates to the data and then write the data as it exits normally. The primary drawback being the 'exits normally' phrase. If it did not exit normally, all of the updates from that run would be lost. It could be extended slightly to write the whole file every time any data changed as long as the target media (hard-drive?) was fast enough that it didn't hold you up from making the next update. Alternatively you could maintain a 'transaction file' with a list of the changes you make as you make them that is deleted after the whole file is written. It would contain data something like "Player 1's Stat 6 is now 12" though in practice the data in the file would likely be [icode]1;6;12[/icode]. When your program starts up and reads the data file, it looks for the transaction file and performs any updates it finds. (If it finds any, I would write the file at that point and then delete the transaction file.)

It has the advantage that the file is probably simple, straight-forward and likely even ...

Murtan 317

If you're running the commview tool on your same computer, I guess the packets are on your network (though I wouldn't have expected them to be).

Is there any way to associate a 239.x.x.x address with your computer (as well as your current ip address) so that you are 'entitled' to the messages?

If not, I vaguely recall a mode for a connection or card that allowed it to 'see' network packets that were not addressed to it. (If commview is seeing the 239 broadcasts I think that's how it works), but I'm not aware of how to put it in that mode.

I remembered the name 'promiscuous mode' for this type of connection. Looking it up as a definition I find:
[url]http://en.wikipedia.org/wiki/Promiscuous_mode[/url]

Murtan 317

So you don't want to append to the file, you want to update its contents?

How many files are there? One per team? One per player? One per stat?

If the file is in ASCII form (like your sample stat was) and you need to update it, you will likely have to re-write the entire file every time you change anything. If the file is small enough and the data is all available, this isn't necessarily a bad implementation.

If the data is organized into fixed size records, you can perform partial file updates by calculating the position to [icode]seek()[/icode] to and just writing the updated data. (Note that seek and open for append don't get along well together.)

Murtan 317

It was my understanding (and I did a little searching that didn't disagree) packets sent to 239.255.255.255 should be available to anyone with a 239.x.x.x address.

Does your computer have a 239.x.x.x address?

Are you listening to the right port?

Murtan 317

Think about it...how would YOU do it?

All you really have to do is additional testing in the year they would turn 18.
If they would turn 17 (or younger) this year they fail.
If they would turn 19 (or older) this year they pass (they're already 18).
If they turn 18 this year you have to compare the months.
If they turn 18 this month, you have to compare the date.

Write some more and ask again if you still can't figure it out, but post what you write along with a specific problem. Something like "It's doing X but I want it to do Y".

Murtan 317

I found this code example
[code=Perl]
use Getopt::Long;
my $data = "file.dat";
my $length = 24;
my $verbose;
$result = GetOptions ("length=i" => \$length, # numeric
"file=s" => \$data, # string
"verbose" => \$verbose); # flag
[/code]

at [url]http://perldoc.perl.org/Getopt/Long.html[/url]

(The first page returned for google "perl getopt long")

If you've read through that page and still have questions, post specific questions with a little more detail on what it does now vs what you want it to do.

Murtan 317

I don't get it...I modified your file only slightly (below) and the run looks like this:
[code]
$VAR1 = {
'C2_GLH3' => 'GLUC + ATP = GLUC6P + ADP',
'A1_HTTT24' => 'GLUC_ext = GLUC',
'B3_PGAI1' => 'GLUC6P = FRUC6P'
};
Enter reaction name for searching:C2_GLH
Can't find 'C2_GLH' in the file
Enter reaction name for searching:C2_GLH3
C2_GLH3,GLUC + ATP = GLUC6P + ADP
Enter reaction name for searching:APPLE
Can't find 'APPLE' in the file
Enter reaction name for searching:B3_PGAI1
B3_PGAI1,GLUC6P = FRUC6P
Enter reaction name for searching:
[/code]

and the output file contains this:
[code]
C2_GLH3,GLUC + ATP = GLUC6P + ADP
B3_PGAI1,GLUC6P = FRUC6P
[/code]

Source:
[code]
use strict;
use warnings;
use Data::Dumper;

my %reacts;
my $database = "reaction_database.txt";
open(Dbase,"<$database") or die "can't open $database $!";

Simplified read loop
Sample input data
A1_HTTT24 : GLUC_ext = GLUC .

while (my $line = ) {

optional whitespace, KEY, optional whitespace, required ':', optional whitespace, VALUE, required whitespace, required '.'
$line =~ m/^\s*(\S+)\s*:\s*(.*)\s+\./;
$reacts{$1} = $2;

}

close(Dbase);

debug to confirm file contents -- left in so I could 'see' something to type

print Dumper \%reacts;

my $input;
open (DATA,"+>react_out.txt") or die "Can't open data";

do {
print "Enter reaction name for searching:";
$input=<>;
chomp($input);
if (not $input=~/^\s*$/) {
if(exists $reacts{$input}) {

feedback on what was matched
        print "$input,$reacts{$input}\n"; 
        print DATA "$input,$reacts{$input}\n"; 
    } 
    else { 
        # explicit feedback for what was not found
        print "Can't find '$input' in the file\n"; 
    } 
}

}until($input=~/^\s*$/);

close(DATA);
[/code]

Murtan 317

Did you try letting the dumper run?
What did you see?

The $1 and $2 in my code are from the regular expression.
They evaluate to the first and second 'groups' in the regex.
[code]
$line =~ m/^\s(\S+)\s:\s(.)\s*./;

The above regular expression is decoded as:
Starting at the beginning of the line ^
Match zero or more white space \s*
Match one or more non-white space (\S+)
saving it as group 1
Match zero or more white space \s*
Match a colon :
Match zero or more white space \s*
Match zero or more of any character (.*)
saving it as group 2
Match zero or more white space \s*
Match a period .

$reacts{$1} = $2;

This then uses the first saved group as the key and the
second saved group as the value

[/code]

You left the split in, but you're using the $1 and $2 from the regex.

Try this (modified from your last post):
[code]
use strict;
use warnings;
use Data::Dumper;

my ($key,$val);
my $database = 'file.txt';
my (%hash,$input);
open(Dbase,"<$database") or die "can't open $database $!";
while (my $line = ){
chomp $line;
$line =~ m/^\s(\S+)\s:\s(.)\s*./;

$reacts{$1} = $2;
my ($key,$val)=split('\s:\s',$line);
$key =~ /([^\s]+)/;

$key = $1;

$val =~ /(^\s+)(.+)(\s.)/;

$val = $2;
$hash{$key}=$val;
}
close Dbase;

print Dumper \%hash;

open (DATA,"+>data.txt") or die "Can't open data";
do {
print "Enter reaction name for searching:";
$input=<>;
chomp($input);
if(exists $hash{$input}) {
print DATA ...

Murtan 317

If you'd post the errors, or what the program is doing that it shouldn't (or isn't doing that it should). I'd have more of a clue as to what to do to help you.

If you're getting a compile error, the actual compiler message along with several lines on either side of the 'problem' would better allow me to help.

If its a run-time error, the actual error message as well as the associated source code would be necessary.

Keep us posted, good luck.

Murtan 317

I don't think you're adding what you think you are. I think the regex match inside the split is overwriting $1 and $2 before you save them.

I would tend to declare $key and $val outside the loop on line 5, and then comment out the split on line 11 to make sure $1 and $2 are preserved -- you don't use the results from the split anyway.

I think that will work.

For debug, you might print all of the key values you add to the hash or with a little more work, you could just print the first ten added or some other subset of the whole.

Murtan 317

You want to put the date and time in the title of the window that pops up, or do you want the name of the directory to contain the date and/or time?

For getting the date/time into a string, you might look at strftime() and you should probably also consider calling mkdir() instead of system("mkdir ...") to create the directory.

Salem commented: Nice +19

Murtan 317

I think what he was trying to point out is that while it is perfectly permissible to compare two integer values using the equality operator "==" that you can't rely on it for double or floating point values.

When comparing floating point values, you usually compare the absolute value of their difference to see if it is less than a threshold. Something like [icode]if (fabs(dblA - dblB) < 0.001)[/icode] which is true if the two values are less than 1/1000 apart. The value 0.001 can be modified to increase or decrease the required precision.

Murtan 317

Here's my test code for the read and store portions...you still need to write the retrieval code. If you have any questions about the code, please ask.

[code=Perl]
my %reacts;
$database = "reaction_database.txt";
open(Dbase,"<$database") or die "can't open $database $!";

Simplified read loop
Sample input data
A1_HTTT24 : GLUC_ext = GLUC .

while (my $line = ) {

Regex [whitespace]KEY[whitespace]:[whitespace]VALUE[whitespace].
# optional whitespace, key, optional whitespace, required ':', optional whitespace, value, optional whitespace, required '.'
$line =~ m/^\s*(\S+)\s*:\s*(.*)\s*\./;
$reacts{$1} = $2;

}

close(Dbase);

debug to make sure I read my data file correctly
I only had the three lines -- you may want to skip this if you have a lot of lines

while ( my ($kk, $vv) = each(%reacts) ) {
print "$kk => $vv\n";
}
[/code]

Murtan 317

I don't see where you're storing them.

Did you possibly mean to declare a hash?

[code=Perl]

declaration

my %reacts;

store one

$reacts{$key} =$value;

test to see if one exists

if exists $reacts{$testkey} { ... }
[/code]

Declare before the read loop
add a store between original lines 11 and 12
use the test in place of original line 21's while loop

Try that and if it doesn't work, post the new code and we'll look at it.

Murtan 317

did you mean to save the key and value pairs you read in so you can search them when you open the second file?

Murtan 317

int variables only hold integer values (-12, 0, 5, 9)
float and double variables hold floating point values (-3.6, 0.1, 5.3, 9.0)

doubles have more precision as to the number of significant digits, but consume more memory.

I prefer to use int (or long) values when an integer value is appropriate as operations using integer values are much faster than their floating point equivalents. I only use doubles for floating point values unless I have a need to use less memory, disk space or bandwidth.

For string input look at gets() or fgets(). I prefer fgets because I can protect my string from being overrun.

Murtan 317

It was a link to another thread that explains why not to use eof() in your while loop condition. Click the link, read the thread and implement the change.

Murtan 317

I wouldn't have written it in the same way, but I think your problem is two-fold:

First, you never set an initial value for [ICODE]DivSales::totalSales[/ICODE] so it's initial value is undefined.

Second, line 21 of DivSales.h where you think you are adding to the total,
[code]
totalSales =+ q0+q1+q2+q3;
// This is the same as
totalSales = (+q0) + q1 + q2 + q3;
// I think you wanted
totalSales += q0 + q1 + q2 + q3;
// That is the same as
totalSales = totalSales + q0 + q1 + q2 + q3;
[/code]

I wouldn't have the class 'own' a total for all the instances. I would have each instance of the DivSales class total its own sales (so it would know all 4 quarters and its own total). I would then add functionality to be able to accumulate DivSales within another DivSales. You would initialize the 'company' DivSales to zeros and then add each of the Divisions DivSales as it is filled in. You could at that point then display the company totals for each quarter and an overall value.

For tabular output I would expect to output something like the following:
[code]
Division Q1 Q2 Q3 Q4 Total
1 225 242 334 326 1127
2 100 100 100 100 400

Total 325 342 434 426 1527
[/code]

Murtan 317

line 24 is passing the address of a function to scanf?
I think you meant [icode]scanf("%f", &inch);[/icode]

line 35 you need to pass the address of restart
[icode]scanf("%f", &restart);[/icode]

Murtan 317

I don't see anywhere that you are not releasing memory you have allocated.

I however, would not have used quite so much allocation. For example the filename is declared and used as follows. The buffer is explicitly allocated, filled, passed to another function and explicitly deallocated.
[code=c++]
char * filename = new char[30];
cin >> filename;
readin(pc, size, filename);
delete [] filename;
[/code]

Using a stack-based local variable is simpler and does not require actual allocation and deallocation. The buffer is declared, filled, passed to another function and released when the function exits.
[code=c++]
char filename[255];
cin >> filename;
readin(pc, size, filename);
[/code]

You may have noticed that I 'sized up' the filename buffer. When you're working with user input, you should have more room available than the user is ever likely to provide. (Some input functions don't check to make sure you have enough.)

I would still argue that the brand and model character buffers should be explicitly sized as well. Your sample program only has 2 instances of the computer structure, but each time you use a computer structure, you have to perform 3 allocations. One for the structure and two more for the character buffers. If the character buffers are always going to be allocated at 15 characters in size, just go ahead and declare them that size. The first allocation would have to go get more memory, but you would not have to make the two additional allocations.

I would have declared it as:
[code=c++]
struct ...

Murtan 317

I'm not sure what the question is.

You declare a pointer to an object of the appropriate type on line 17, in most linked lists I've seen, it is usually named "next" but other than that I don't see a problem.

You do appear to be declaring one on line 23 as well, or was that supposed to be an accessor?

If is were my implementation the private member would be [icode]ProcessedPayroll pNext;[/icode] and the accessor would be [ICODE]ProcessedPayroll getNext()[/ICODE] and the mutator [ICODE]void setNext(ProcessedPayroll * next)[/ICODE]

For the rest of the linked list, you need to have a "head" pointer that either points to NULL if the list is empty, or the first object in the list. The last object on the list will have its "next" pointer point to NULL.

How things are added to the linked list depends on the importance of ordering to the list. For a standard linked list, it is easiest to add elements at the head, but then when the data is accessed in the normal fashion, the data is in the opposite order from how it was added. (The last added would be the first seen.)

If the elements are to be added to the end of the linked list to maintain the order, you must either iterate to the end of the list every time you want to add one, or maintain a pointer to the "tail" (last object in the list -- NULL if the list is empty).

I ...

Murtan 317

You put your variable definitions in a .py file you could name it definevble.py if you wanted to.

Then from the other python file (.py) that wanted the variables you add a line:
[code=Python]
from definevble import *
[/code]

That imports everything in that file into this file.

I think that will do what you want.

For example if vardefs.py contains:
[code=Python]
pie="Apple"
[/code]

and vartest.py contains:
[code=Python]
from vardefs import *
print pie
[/code]

The output of vartest.py will be "Apple"

Murtan 317

At first glance, it looks pretty close to me.

So I loaded it up in Visual Studio, cobbled together a data file named "data." using notepad and it seems to run for me.

The data file contains:
[code]2
Dell Inspiron 299
Hp Pavilion 499
[/code]

When I run the program I get:
[code]
enter the file name :
data
brand:Dell model:Inspiron price:$299
brand:Hp model:Pavilion price:$499
Press any key to continue . . .
[/code]

That looks right to me.

What are you seeing?

NOTE: I did explicitly over-ride the default working directory to the directory where the data file was created. Either do that or make sure your data file is in the correct directory or the program won't be able to find it. Alternatively, you could enter the full path to the data file, but you only allowed 30 characters so don't overflow it.

Murtan 317

You appear to be having some trouble with scoping.

No function can see the local variables of another function unless that other function passes them as arguments.

The filename declared on line 19 is the one that main puts the name the user enters into. The filename declared on line 47 and used on line 48 will NOT contain the filename. So to start with, you aren't opening the right file in readin().

You could easily add another parameter for the filename
[icode]readin(char filename, computer & pc, int size);[/icode]

Also, readin() if it reads the right file, reads in the size and main and printF expect to be able to use the size, but the size is local to readin(). If you want readin() to set the size and for main to see it, you have to pass the size by reference (like you did the computer array.) [icode]readin(char filename, computer & pc, int & size);[/icode]

To simplify the rest of the code, you could skip allocating character strings for the brand and the model by just declaring them with size in the structure:
[code=c++]
struct computer{
char brand[15];
char model[15];
double price;
};
[/code]

(As a matter of personal preference, I like declared types to start with a capital letter and I like indenting so my declaration would look more like this:
[code=c++]
struct Computer {
char brand[15];
char model[15];
double price;
};
[/code]
but it is your code.)

readin() just allocated the array of ...

Murtan 317

any chance you can post what you have now (in code tags) so I can look at it?

Murtan 317

If your data file really looks like:

[quote]
2
Dell inspiron 299
Hp pavilion 499
[/quote]

You will not be able to use a standard stream read for the name. The standard string read will stop at the first space. You will need to perform something like a line read (see getline()) and then parse the string you read to find the number at the end of the line.

Murtan 317

the [ICODE]ifstream fin[/ICODE] on line 48 inside readin() is NOT the same as the stream of the same name that is declared on line 20 and opened on line 24 in main().

You either need to open the file in readin() or pass the stream from main into readin().

Murtan 317

I don't want to spend the time to figure out if your program does exactly what the spec calls for, I'd rather help you get your program to do what you expect.

What are you seeing it do that is unexpected?

(What are the symptoms)

You might want to add some temporary debug output (or run the program in a debugger) so you have a better idea of what is going on inside.