raptr_dflo 48 Posting Pro

mzimmers, the algorithm isn't really "sorting a stack", it's using three stacks to sort an arbitrarily-ordered input sequence. Step 2.1 and 2.2.* basically say "transfer all elements except the largest from stack 'in' to stack 'temp' (order doesn't matter here). The rest of step 2.* is "push the largest onto stack 'out'", and move everything from 'temp' back to 'in'". The last bit of that isn't a typical stack operation, but could just as easily be addressed by repeating step 2, only moving all but the largest element from 'temp' back to 'in' and pushing that next-largest value onto 'out'. If you want your head to start spinning, take a look at the PostScript programming language -- it's all about manipulating a stack, with almost no ability to define scopes! :(

fanfunstar, I suspect you're doing fine the way you are, and that the instruction to "use linked lists" means to implement your own stack. If you don't understand how to implement a stack using a linked-list, then just stick with what you're doing for now. But my questions from my original response still hold: What specific errors or incorrect output are you seeing? Can you figure out how to "clear" a stack by yourself? Also, I think your statements are reversed at lines 27-28 in the code you posted originally (though you may have changed it by now). With any luck, that will be enough to get you running.

raptr_dflo 48 Posting Pro

Also, are you supposed to be using the STL stack implementation, or is the purpose of your assignment to create your -own- stack implementation?

If the former, no problem, you may just need to manually clear your temp stack. How would you go about getting rid of each value on a stack, if you no longer need any of them? Also, the line [code]in = temp;
[/icode] may or may not do what you need, but we can get to that if we need to. More importantly, what do you mean by "my code isn't working"? Are you getting compiler errors? Does it run but not print what you expect to see? We can't see your screen (or read minds); you have to tell us specifically what's going wrong.

When you re-post your revised code, please select it all and click the "[ CODE ]" button at the top of the editor (which will put "[ CODE ]" in front of it and "[ /CODE ]" after it [both without the embedded spaces]). This maintains your formatting and adds the nice line numbers, so we can all better read and comment on your code. Thanks!

raptr_dflo 48 Posting Pro

A worst-case situation for buildHeap (having your array pre-filled with values and having to shuffle those values to create a minHeap) is one in which the first value is greater than at least one of the next two, so that a swap is needed there, and then after that, the same holds true for each of the sub-heaps rooted at those children. Plus, once you've (recursively) fixed each child heap, its root now again needs to be exchanged with its parent. My bet is that an array sorted into reverse order (largest element first) is going to represent a huge amount of work to turn into a minHeap.

As far as insertion into a valid minHeap, a new value is presumably added to the end of the array, and then the heap is "re-heap-ified". Again, a worst case scenario is if you keep adding smaller values to your heap, since they will need to be percolated all the way up to the root each time. Is it always the case that once a new value is inserted and percolated part way up the tree-structure, it will never need to move down a different branch? Why? What does this tell us about my argument thus far?

raptr_dflo 48 Posting Pro

I'm running Windows7 here, so the details might look a little different on your computer, but you should be able to get to the Add/Remove Programs dialog, and remove VS2010 from there, and it should correctly remove only what it installed that isn't also needed by something else (e.g. your VC++ installation). At worst, you'll have to go back and reinstall VC++, but that shouldn't be hard either.

Now here's what I have:
From the Windows "Start" menu in the lower-left corner of the screen, I choose "Control Panel" (over in the right-hand column of options).
My Control Panel is organized by topic, so I choose "Programs"
Under the first section, "Programs and Features", I choose "Uninstall a Program"
Then I wait because I have so much junk installed on this box.... :)
When I scroll down, I see 5 items specifically labeled "Microsoft Visual Studio 2010 ..."
A good one to start with, in my case, is "Microsoft Visual Studio 2010 Ultimate - ENU" ... that sounds like the main entry point.

Start by uninstalling that one (and the other 4, if they don't go by themselves). Since it's unlikely that I did any other installation work that day, I could go through and find other items that have the same installation date, and guess that they were installed as part of the same effort and uninstall them as well. With any luck, picking a good start-point will get rid of …

raptr_dflo 48 Posting Pro

I'll take a stab at this, but others please correct me if I'm confused. There are two potential paths to take when -creating- a library ... static vs. dynamic.

If you create a "static library", you end up with a large .lib file which contains all the compiled code for the functions in that library. If you then create an executable using that library, all of that code is copied into the executable at link-time (compile-time: when source code is analyzed and turned into compiled object code, link-time: when various object files and libraries are "linked together" to create the final executable). This makes a larger executable, but one that doesn't depend on a separate DLL file at run-time.

If you create a "dynamic library", you end up with a large .dll file and a small .lib, as previously described. All of the compiled code for the functions in the library is in the .dll file. Now your final executable is smaller, since the code is -not- copied into the executable at link-time, but the .dll file has to be sent along with the executable, unless you can rely on it already being correctly installed on the end-user's computer.

The advantage of dynamic/shared libraries is that many different programs which need the same set of functions can all get that code at excutable load-time, rather than having that compiled function code copied into each executable. In addition, this is mostly how "plugins" are handled -- except now …

raptr_dflo 48 Posting Pro

Everything is possible. Reagrdless of how quick-and-dirty you're trying to be, take good advice when it's given. main should almost always be declared as:

int main (int argc, char *argv[])
{
    ...
}

And there's almost never a reason to call it from inside itself or any other part of your program. When you absolutely need to call main() yourself, you'll know. Until then, just don't do it.

I don't know why you'd want a user-input-controlled loop to be implemented using recursion (the function calling itself over again if the user wants to repeat), but that's not the aspect that's not working. At least consider having repeat() call itself instead of calling main().

Also, the assumption should be that exit() is called only from main() (as a replacement for a simple "return" statement). Someone reading your code should expect all function calls to return execution back to their caller, and ultimately to main(), which will call exit() or return as appropriate to end your program.

If you've fixed your if() expressions and your code still doesn't work, please post the revised code so we can see what else might have gone wrong.

Thanks.

raptr_dflo 48 Posting Pro

And you still have a local variable int size; declared near the top of your main(), which masks the global constant const int size = 1000; . Get rid of the one inside main(), it's not needed and it's causing problems.

raptr_dflo 48 Posting Pro

For one thing, if printSentence() and fprintSentence() are identical except for whether you pass in and use an ofstream&, or just use cout ... then why not just do:

void printSentence(vector<Clause> clauseArr)
{
    fprintSentence(cout, clauseArr);
}

Then, is it obvious to you that your first incorrect output line looks very much like the correct first output line, except duplicated? Among other things, this should indicate to you that your fprintSentence() function should probably output endl at the end of the loop.

Then look at what's different in your literal-parsing code between lines 33-43 and lines 309-318. Maybe you should move the correct code into a parseLiteral() function that you can call from each place?

Once you have the correct set of initial clauses, we can see what needs to be fixed next.

raptr_dflo 48 Posting Pro

Does it work if you replace outFile.open("out.data"); with outFile = cout; ? With this change you should at least see output to your terminal or IDE output-window.

If you have a problem opening "out.data", your error-statement at line 11 will fail. You can't output an error message to a stream that you failed to open! Use cout (or better yet, cerr) instead.

Then, after reading your input file, you call printArray with variables first and last uninitialized. Presumably you'd at least want to hard-code them to 0 and MAX_SIZE-1, although you should be smarter about verifying that you were able to read MAX_SIZE values from your input file.

raptr_dflo 48 Posting Pro

It really depends on how you want to architect your game. In this article/lesson, LazyFoo is discussing an object-oriented state-machine, where each state acts like its own mini-program, handing off control to a different state/mini-program, depending on the user's input. So each state needs its own event-loop, and each loop needs to call a SDL_PollEvent( &event ) to see what the user is doing.

Another alternative is to have a single event-loop, and give each state a handle_event(const SDL_Event & event) method to handle a single event (just take out the surrounding loop from handle_events() . The advantage of this approach is (in addition to managing a single event loop in your program) that if the user can enter events faster than the event-loop is cycling (which should be rare these days anyway), you change which "state" is handling events right at the event that requires the state-change ... rather than having a stale state continuing to eat future events until the queue is empty, before the main-loop gets control back and handles the state-change.

raptr_dflo 48 Posting Pro

Thanks for the clarification. There's still a logic error in your loop eliminating letters out of dictionaryword: what happens if a letter in givenword occurs more than once in dictionaryword, for example if givenword is "TENT" and dictionaryword is "TEE"?

raptr_dflo 48 Posting Pro

Sorry, I'm not sure what your question is. The "+" operator for strings is defined as "an external function" (instance methods require that the implicit first parameter be the "this" pointer to the current object instance, but don't worry about that detail right now). Here's some code, with comments (see this for more details):

std::string hello = "Hello";  // this uses std::string operator= (const char *txt)
std::string world = " world";  // this also
std::string ex1 = hello + world;       // OK:  uses std::string & operator+ (const std::string & one, const std::string & two)
std::string ex2 = hello + " world";    // OK: uses std::string & operator+ (const st::string & one, const char * two)
std::string ex3 = "hello" + world;     // OK: uses std::string & operator+ (const char * one, const std::string & two)
std::string ex4 = "hello" + " world";  // ERROR: since the "+" is evaluated before the "=", it has no idea that what you're trying to create is a std::string, so it can't do anything intelligent at all
raptr_dflo 48 Posting Pro

And as far as printing "1" each time, what are you printing? Why would you expect it to print anything else? If you can't answer this, do what WaltP recommended, and draw your list, one node at a time, as you build it. Not what you -think- it's doing, but following your own code, one line at a time. Then it should be obvious what's wrong.

raptr_dflo 48 Posting Pro

You already -have- declared a and b, you do it inline as part of your for() statement, rather than separately, but since you don't use them outside the scope of those loops, it's fine.

The two problems remaining are:
1) After the sort, you use "nums" for your loop counter, instead of going back to t. By itself, it wouldn't be a problem, but why switch? Consistency is a good thing.
2) What's actually causing your problem now, which affects using "nums" for your loop counter, is you've declared nums as an int. So when you use it as a temporary variable in your bubble-sort code, you're throwing out the fractional part of the values as you bubble a value down past them. Since arr[] contains doubles, your temporary value should be a double also. A float or double can be used to control a loop, but should be done carefully. Since array indices are integers, that's the type to use to loop over elements in an array (regardless of the type of values in stored in the array.

Good luck!

raptr_dflo 48 Posting Pro

Where you specify a.length() and b.length(), do you mean x and y? And which is which? Please use more meaningful variable names so other people looking at your code don't have to guess what each variable represents.

I think in your loop of p, you need to handle what happens if you -don't- find the character you're looking for, but since I can't tell which word is which, I'll leave that to you.

raptr_dflo 48 Posting Pro

Your way is just fine. Good work! (Sorry, I'm doing too many things at the same time here.) And don't forget to mark your thread as "solved". :)

raptr_dflo 48 Posting Pro

Since 'A-F' and 'a-f' are separate from '0'-'9' (the characters, not the integers), you would handle them separately, like:

if (*readPtr >= '0' && *readPtr <= '9')
  hexVal = int(*readPtr - '0');  // since '5' is 5 places up from '0', '5' - '0' evaluates to 5
...

Keep in mind that while you can do the same thing with 'a'-'f' and 'A'-'F', that 'a' - 'a' is zero, not 10, so don't forget to add the 10 to get the correct value!

raptr_dflo 48 Posting Pro

If you're learning about functions, then now is the perfect time to start creating some, right? :)

You can put your code fragments all in one program by simply pasting them into the center of:

#include <iostream>
#include <stdlib.h>

int main (int argc, char *argv[])
{
   // program code goes here

   return 0;
}

As far as "flows well", I have no idea what you'd like it to do. That part is entirely up to you. What do -you- mean by "a single program ... that flows well"?

raptr_dflo 48 Posting Pro

You were doing well with the code you originally posted in the other thread. Or was that somebody else's code you posted? Anyway, your loop for displaying the contents looks fine. The conditional expression for your for() loop (the expression in the middle) is equivalent to clist->ptr != NULL , other than if there should be only one node per value, then you don't want to quit when clist->ptr is NULL, you want to quit -after- you print that node:

for (clist = top; clist != NULL; clist = clist->ptr)
    printf("%d\n", clist->data);

The problems are (a) yes, you forgot to NULL-out the ptr for the last node in the list, (b) you're still allocating the data size incorrectly (this was pointed out in your previous thread), and (c) you're not thinking about when to allocate. For the last point, since you need one linked-list node per value of interest, then there's no need to allocate a node outside of your for-loop: loop over i, allocate a node, assign the data, set the ptr to NULL, "hook it on the end of your list" (your use of the clist pointer pretty much does this, just clean up the order in which you do things).

And don't do the print-loop inside the create-linked-list loop, you're potentially corrupting your clist variable that way. Build the list in one loop, then after that, print it out in another loop.

raptr_dflo 48 Posting Pro

Command-line argument handling is certainly a challenge, especially if you want to respond properly to mal-formed entries like "-option=val=somethingextra" or "-option =val" (note the embedded space). To start, assume the user will at least use correct arguments and formatting, so all you need to do is get the name and value.

Since you don't know which optional arguments you will get, you need to loop over the arguments you have:

for (int arg = 2;  arg < argc;  arg++) {
   ...
}

Inside that, for each argument, you need to determine which one it is. A simple strncmp() call will do that:

if (strncmp(argv[arg], "-price=", 7)) {
    ...
}
else if (...)

Then you need to extract the integer-value from the correct position in the string:

price = strtol(argv[arg] + 7);

And finally, it's useful to keep track of whether you saw that argument at all:

gotPrice = true;

This is a very C-centric approach (you could instead make a temporary std::string from the argument, find() the substring of interest and verify it's found at the start, create a strstream from it, and use the stream-input >>-operator to get the value), but should work with a minimum of fuss.

The rest of the logic should be easy enough to work out. The number of optional arguments is argc-2, again assuming no errors, and the user hasn't done something silly and specified the same argument twice (whether with the same value or different values).

raptr_dflo 48 Posting Pro

Your code at line 3 is valid because the + operators associate left to right. The first thing it computes is, effectively const string tmpString1 = "*" + greet_space; which is valid because only the first argument is a string-literal. Then it does const string tmpString2 = tmpString1 + greeting; and so on, each of which works because the first paramater is always a std::string type. Then at the end it does const string greet_write = tmpStringN; to assign the "sum" (concatenation, really) to your variable.

Does that answer your question?

raptr_dflo 48 Posting Pro

Since you've been told to use pointers rather than array-indexing []-notation, don't think of it so much as "how can i ... put that character back into the string" as "once i've determined the character and replaced the %-sign with it, how do I get rid of the two hex-digits?" Hint: since your replacement will always be shorter than the original text (one character instead of a 3-character %XX hex pattern), if you maintain a read-pointer and a write-pointer, then you can keep copying the character at the read-pointer down to the position of the write-pointer until you hit the next %-sign and then evaluate another encoded character.

The first bit is: do you understand hex notation? If you know, e.g. that %d3 is 211 (in decimal), and why, then it should be reasonably easy to say something like: "if read-ptr points to '%' then val1 is the character after that converted to an integer in the range [0,15], and val2 is second character after that, converted the same way. The byte-value of the two hex-values is (... a number in the range [0,255] ...). And that, converted into a character is '...something...'. And that's what gets written to my write-pointer, and then I move each pointer forward by the correct amount."

What you need to fill in is:
how to convert a hex-digit character to an integer hex-value
how to combine the two hex-values into a single 8-bit integer
how to convert an 8-bit …

raptr_dflo 48 Posting Pro

Since your main() and your yesno() function appear to do almost exactly the same thing, you probably should spend a little time re-thinking your whole program, as short as it is.

If you were to ask me (not that you did), I'd say a function called yesno should only ask the user if he wants to run the program again, and return true if he does, false if he doesn't and loop until his response is valid. Meaning its return type should be bool rather than int, and should probably be called something more specific, like runAgain(). Then you could do something like (this is pseudocode, but making it C++ is not hard):

keep doing {
   get a number from the user
   compute factorial
   display result
} while runAgain() returns true

Your code will be much smaller and more manageable.

That said, yesno() currenty returns an int (0 or 1), but in main() you not only assign it to choice (a variable of type char), and then don't look at that value of choice once you've returned, but the variable is in fact local to that else-if block, since you redeclare it there (specifying "char" again makes a new local variable that masks the one in the outside scope).

Then inside yesno(), you have that function call itself twice. Once in the same else-if block, again assigning the int result of the recursive call to a local char variable which you then ignore and just return …

raptr_dflo 48 Posting Pro

A probable cause of problems is certainly in your fillParent() routine:

Node fillParent(Node l1, Node l2){
    Node new1;
    new1.freq = l1.freq + l2.freq;
    new1.right = &l1;
    new1.left = &l2;
 
    return new1;
}

You're passing l1 and l2 "by copy", meaning that whichever two nodes you pass into the function, your program makes two new nodes (called l1 and l2) which are copies of the nodes you provided, but exist only within that specific call to fillParent(). You then create a new node, which points to each of the copies, and return a copy of that new node (which also points to the same two copies), and the original new node is destroyed (which is fine). The problem is that the two argument-copy nodes are also destroyed when the function returns, leaving your returned parent-node copy pointing to garbage. You can neatly avoid most of the unnecessary copying, and resolve your problem at the same time, by passing the arguments "by reference". The only change is in the notation of the argument list, note the added ampersands ('&'):

Node fillParent(Node & l1, Node & l2){
    Node new1;
    new1.freq = l1.freq + l2.freq;
    new1.right = &l1;
    new1.left = &l2;
 
    return new1;
}

In this way, l1 and l2 are referring to the actual nodes you passed in, rather than copies of those nodes, thus the phrase "pass by reference". It is nearly the same as passing pointers to the nodes, and then dereferencing the pointers inside the function.

raptr_dflo 48 Posting Pro

Assuming you're running Windows (which isn't necessarily a valid assumption), you're probably interested in the function GetAsyncKeyState() described here. In general, while it isn't always obvious what function you may need, or how to filter out all the irrelevant chatter, http://msdn.microsoft.com/ seems to be the go-to reference source for all things Windows. (I'd been a *nix developer for years, and avoided the Windows-based PC world until just the past couple of years.)

raptr_dflo 48 Posting Pro

The most obvious answer is, there isn't a function called "Assembler" in the DLL. Maybe there's a typo in how you built the DLL, or in what symbol-name you're expecting to find in it?

raptr_dflo 48 Posting Pro

Think about what it means "if characters in GIVENWORD can form words in DICTIONARY array". Break that down into smaller steps. Options include
1) Make every possible sub-word from GIVENWORD, and then see if that sub-word is in the dictionary.
2) For every word in the dictionary, see if you have the right letters in GIVENWORD to make it.
Either should work fine. Extra credit if you can get it to work both ways! A hint on the second method: put the letters of GIVENWORD into a temporary array, and then "remove" each as you use it to form the dictionary word -- instead of -actually- removing a letter, what could you replace it with so that it couldn't be accidentally re-used? E.g. you can make "TENT" from "TENANT", but you can't make "TEE" from "TENANT". Think about how you'd solve this problem on paper: "Can you make word A from the letters in word B?" And then translate that process into code.

raptr_dflo 48 Posting Pro

Near the top of your main():

if(inFile.fail() || outFile.fail())
{
    outFile << "Input or Output file ERROR!" << endl;
}

but if outFile is in a fail-state, you probably can't output to it! Try instead:

cerr << "Input or Output file ERROR!" << endl;

This will at least tell you if there was a problem opening the files. Also at this point, your program should probably give up, since it either won't be able to read in the input data, or else won't be able to write the output, so add also add:

return 1;

at the same time.

raptr_dflo 48 Posting Pro

You're re-using variable t as an int counter (in your loops) and as a temporary placeholder during your swap (intending it to be a double at that point). It may not affect your answers, but try using variables longer than one-letter, and making sure that each only has one purpose and one type per function.

Other than that, tell us what decimal numbers you're entering (and in what order), and what gets printed out as the sorted array. That might make it more obvious what's going wrong.

raptr_dflo 48 Posting Pro

I'm not positive, but I think the problem is that

char val;
cin >> val;

doesn't do anything until you also hit enter/return (which puts an additional '\n' character on the stream). Then when you do

getline (cin,newStdName);

you actually get an empty line since the '\n' is still there. A quick solution would be to insert

cin.ignore(80, '\n');

before your call to getline ... this ignores up to 80 characters followed by the '\n' which you know is there. In fact, at this point, it might also work to type 'yes' instead of just 'y' at the previous prompt. Feel free to play around with it. There's a longer, detailed tutorial here, but don't worry yet if you don't follow everything in it ... the long and short of it is, unfortunately, that iostreams were so badly defined and implemented that it's a wonder we can use them at all. Well, maybe not -that- bad.... :)

raptr_dflo 48 Posting Pro

Take another look at your SearchThis() function -- what does it do to your Head pointer? Probably not what you intended to have happen. Instead use a temporary pointer as you do in addNod(). Also, what happens if the string isn't in the list at all? It doesn't look like you handle that case.

Gotta run, I'll check back a bit later.

raptr_dflo 48 Posting Pro

Same way you do the binary search in other places, or (for case 6) since you've already done the search, you should know about where you are.

insertIndex is the value of i where (StdRec[i-1] < stdIDInput && stdIDInput < StdRec[i]) . Keep in mind the edge conditions stdIDInput < StdRec[0] (new record goes at the beginning, there's no StdRec[-1]) and stdIDInput > StdRec[NUMRECS-1] (new record goes at the end, there's no StdRec[NUMRECS]). Do your binary search by hand on a set of 3 records and various new values for stdIDInput. Or add a debug cout << ... line after your while() loop. What are the values of first & last at the end of the while() loop, when you've failed to find the new ID? inputIndex will be one of these values, or very close to it.

raptr_dflo 48 Posting Pro

You need to put

extern std::ofstream outf;

in a header file, and include that header file in any source file that needs access to outf. That just says that outf is of that type, and will actually be allocated -somewhere-. Then in -one- of the source files, you still need to specify:

std::ofstream outf;

in the global scope (outside of any function, otherwise it's a local variable of that function), e.g. as you previously had it in main.cpp

But whether outf is a global variable or passed into each function which needs it, is irrelevant to your "experiment". Unless you're using a specialized concurrent version of C++, your code as written will only execute one reader or writer, all the way through, and then another. The "processes" will never execute concurrently.

Go back to the assignment and understand how to implement a "process" as directed, so that it each time it is called, it executes only the next instruction and immediately returns, to approximate concurrency.

raptr_dflo 48 Posting Pro

Just mark the thread as "solved", they don't get deleted except in extraordinary cases. Thanks for trying to clean up though! :)

raptr_dflo 48 Posting Pro

I think you have many problems with your Resize method:

template<typename T>
T Lottery<T>::Resize(T* array, int i)
{
    T* arr3= new T [i];
    delete[] array;
    return array3;
}

You have (1) dynamically allocated a new array of i objects of type T, and done nothing with it, (2) deleted the array that you passed in, for no obvious reason, and without doing anything with it, and (3) returned a variable that isn't defined.

So I think that needs work before you get too far. Once you determine what you need to pass in to a Resize method, vs. what information the class instance already has, I think you'll find that the error message becomes a non-issue (though if you really want to know, it's because the first variable you're passing into the method is an integer, when it's expecting and array-of-integers).

raptr_dflo 48 Posting Pro

I am unable to understand your code

last_played=new Time (*so.getLastPlayed()); // You are using so as reference(const Song &so) then why you are trying to call with "*" . This call should be  so.getLastPlayed()

the .-operator (element-of-object) has a higher precedence than the *-operator (dereference-pointer), so the OP's code is equivalent to:

last_played = new Time (*(so.getLastPlayed()));

The problem might be that so.getLastPlayed() is returning a NULL pointer. In that case, what should this->last_played be set to? And why is it returning a pointer in the first place? If it returns a const Time & instead, then we don't have this problem....

raptr_dflo 48 Posting Pro

Googling around for glGenVertexArrays got me this on the 5th entry, does it help?

raptr_dflo 48 Posting Pro

This is what we're discussing towards the end of your other thread. You need to keep track of how big your array is (how many student-records you could have) and how much is used (how many student-records you actually have), and then don't try to look at a student-record that couldn't possibly exist because it would be past the end of your array.

raptr_dflo 48 Posting Pro

If you then want to make your array bigger instead of printing an error, your array allocation should look something like this (note that MAXRECS is no longer "const"):

int MAXRECS = 20;
int NUMRECS = 0;
StudentRecord *stdRec = new StudentRecord[MAXRECS];

...

if (NUMRECS == MAXRECS) {
    // need more space
    int NEWMAXRECS = MAXRECS * 2;  // let's get twice as many
    // reserve bigger array of records
    StudentRecord *newStdRec = new StudentRecord[NEWMAXRECS];
    // copy existing records into new space
    for (int i = 0;  i < NUMRECS;  i++)
       newStdRec[i] = stdRec[i];
    // delete old records-space now that we're done with it
    delete [] stdRec;
    // point the original name to the new array, and update the size
    stdRec = newStdRec;
    MAXRECS = NEWMAXRECS;
}

Note that you can treat a pointer-to-a-record the same as an array-of-records, as long as you've allocated the space for the array. In fact, in C and C++, if you declare SomeType arrayVar[someSize]; then arrayVar is identical to &arrayVar[0] , the pointer to the beginning (zero'th) element in the array.

raptr_dflo 48 Posting Pro

For now, start with your array bigger than you need at first, and keep track of how big you made it, and how many valid records are actually in it. If you run out of room, print an error. Don't think of it as "adding records", think of it as "filling in the empty records that are already there", if that helps.

const int MAXRECS = 20;  // or however many you need
StudentRecord StdRec[MAXRECS];  // all empty at this point
int NUMRECS = 0;  // there are no filled records in the array

...

// user wants to add a record
if (NUMRECS == MAXRECS) {
    cout << "Sorry, there's no more room to add a new student record" << endl;
}
else {
    // find insertIndex where to add a new record so that the array stays sorted:
    // such that stdRec[insertIndex-1].studentID < stdIDInput < stdRec[insertIndex].studentID
    // move records with (ID > newID) up one position -- opposite of when you delete
    for (int i = NUMRECS-1;  i >= insertIndex;  i--)
        stdRec[i+1] = stdRec[i];
    // copy data into freed-up record
    stdRec[insertIndex].studentID = stdIDInput;
    ...
    // update current number of used records
    NUMRECS += 1;
}
raptr_dflo 48 Posting Pro

You need to read the file in "binary mode". While you can probably do the same thing with fstream, I honestly have never bothered learning how. The C way to do it uses fread() on a FILE* object:

#include <stdio.h>
#include <iostream>
using namespace std;

...

FILE *fp = fopen("C:/Users/DFlo/Pictures/13.jpg", "rb");
unsigned char magic[4];
fread((void *)magic, 1, 4, fp);
cout << hex << "magic:";
for (int i = 0;  i < 4;  i++)
    cout << " 0x" << int(magic[i]);
cout << dec << endl;

Note that fopen() return NULL on failure, and fread() returns the number of items read (should equal 4 in this case).

raptr_dflo 48 Posting Pro

Hi BubblesBrian,

Programming is a very precise activity. Whether you understand while() loops or not, you will likely find it a frustrating process until you learn to express what you're trying to do clearly and precisely. On the flip side, once you can do that, you'll likely find that the code almost writes itself!

Maybe a construct like the following would prove useful?

bool quit = false;
while (! quit) {
    bool allowBuying = true;
    if (money <= 0.0)
        allowBuying = false;
    if (allowBuying) {
        cout >> "Would you like to buy or sell (B/S)?";
        ...
    }
    else {
        cout << "You are out of money.  Would you like to sell (Y/N)?" 
        // if no, set quit = true;
    }

    if (quit)
        continue;  // go back to top and then exit loop, or "break" to exit now
    
    // do other stuff
}
raptr_dflo 48 Posting Pro

From Visual Studio, choose "Clean Solution" from the "Build" menu. This should delete all the intermediate build files and final targets, leaving only the source files. From there, it will -have- to rebuild all the files, so you should be OK after that.

raptr_dflo 48 Posting Pro

Line 77 (and the other ones like it) could be replaced much more succinctly with:

if (newStdCreditPoint >= 0  &&  newStdCreditPoint <= 240  &&  newStdCreditPoint % 10 == 0)

The %-operator (called "modulo") returns the remainder left over after dividing the first number by the second. In this case the expression val % 10 == 0 says "val can be divided evenly by ten with nothing left over".

I suspect your crash might be happening at line 48 rather than line 42, but I'm not running your code, so I don't know. There's nothing wrong with the code where you've marked it. At line 48, I'm concerned that you might be trying to assign to an student-record past the end of your array.

Your logic for error-checking your input is bewildering. Instead of looping while the response is 'Y' and breaking if the answer is 'N' (which do the same thing, so only one would be necessary), loop while the input value is invalid (and still break if the user doesn't want to try again. Then use the validity to decide whether to prompt for the next value:

bool idValid = false;
bool courseCodeValid = false;
bool creditPointValid = false;
do {
    // prompt for id
    // get id from user
    if ( /* id is valid */ )
        idValid = true;
    else {
        // prompt for try-again
        // get try-again from user
        if ( /* try-again is not 'y' */ )
            break;
    }
} while (! idValid);

if (idValid) {
    // proceed to next thing to input
}

if (idValid && ... ) {
    ...
}
raptr_dflo 48 Posting Pro

your prototype in spherefunction.h says all four strings should be const std::string & , yet your implementation in spherefunctions.cpp sepcifies that only the first one should be const. Keep all four const -- const-ness matters, especially when passing references: non-const reference variables can be modified by the function they're passed to, but clearly hard-coded strings aren't variables and can't be modified, thus if passed into pass-by-reference arguments, those arguments MUST be qualified as const.

raptr_dflo 48 Posting Pro

You have to respecify mid. It should still be (first+last)/2, but its value doesn't change just because you go behind its back and change first and/or last, any more than if you had arbitrarily said mid = 5; ... once you assign a value to a variable, it keeps that value until you assign it a different value. So if first and last start out as, for example, 0 and 20 (if you have 21 students in your array), then mid starts out as (0+20)/2 = 10, but it stays at 10 until you recompute what the new midpoint is between the revised-first or revised-last.

As far as "just stops", it's actually getting stuck in an infinite loop at that point, because if it doesn't find it at the first value of mid, then first or last is assigned a new value, but mid doesn't change, so first & last also don't change after that point, and it keeps checking the original position of mid (which still doesn't match), and reassigning the same modified value to first or last, depending on which side it should check next.

raptr_dflo 48 Posting Pro

Aha! When you recompute first or last, make sure you update mid at the same time (after lines 30 and 34, respectively)!

When adding a new student record, make sure that you've allocated enough records in your array. You need to separately keep track of MAXRECS (the total number of records allocated in your array) and NUMRECS (the number you're currently using). If NUMRECS == MAXRECS, then you have no additional space and can't add a new student. If this is something you need to address for this assignment, we can discuss dynamic memory allocation and/or using a std::vector<> instead of a static array. Otherwise, just print an error message to the user. Also, it doesn't do much good to assign studentCount from NUMRECS, and then not eventually increment NUMRECS. One variable for this purpose is sufficient.

raptr_dflo 48 Posting Pro

OK, continuing on, your default sphere() constructor declares a local-variable radius which masks the member variable ... note how your next constructor, which takes an argument, simply sets the radius (but doesn't re-declare it as int).

Then your GetRadius(), CalcCircumference() and CalcVolume() methods are all declared that they return a value, but none of the implementations actually specify a return statement to return a value. The latter two also declare a local variable of type double but are declared to return type float. Pick one or the other, or (for maximum readability) explicitly cast the computed value to the return type when returning it, e.g.: return (float)value; Your loop for radius values between 20 and 30 (inclusive) looks fine, but is it the sphere-instance's job to perform that loop? Think of it in terms of what you really need to do: loop over different radius values, and then determine (and print) the circumference and volume of a sphere with that radius. Sounds like the loop should exist -outside- of the sphere implementation:

sphere s;
for (int r=20; r<=30; r++) {
    s.SetRadius(r);
    float c = s.CalcCircumference();
    ...
}
raptr_dflo 48 Posting Pro

No, I think you have it backwards. While that would be easy, it doesn't get you any closer to generating the correct output. What you want in the linked-list is the latin words, so that you can print out the results by traversing the BST in-order to get the English words in alphabetical order, and then print out the corresponding Latin words for each English word.

Keeping it very specific, given the first line for Unit 5:

ante : before, in front of, previously

you will need to insert "before" and "in front of" and "previously" into the BST, each with the corresponding Latin word "ante". Each bst_node needs:

string englishWord;
LinkedList latinWords;

Does that help?

raptr_dflo 48 Posting Pro

Looking just at the actual code in sphere.h:

class sphere {
    int radius();
 
public:
    sphere();
    sphere(int InRadius);
    void(SetRadius(int NewRadius));
    int GetRadius();
    float CalcCircumference();
    float CalcVolume();
};

radius is presumably your member variable, so it should not be declared as though it's a function. Try int radius; at line 2. Also, what's with the extra parentheses around SetRadius at line 7?

We can go over sphere.cpp next, but I think you need to answer the first couple of questions first. Where do -you- think those variables should be declared? Where do -you- think the calculations should be performed?