Banfa 597 Posting Pro Featured Poster

Normally it's liters/100 kilometers but ignoring that detail.

If you have C in miles/gallon then you need to do 3 convertions

miles -> kilometers = times by 1.609
gallon -> liters = times by 3.785 (but note that gallons in underneath the line
distance/volume -> volume/distance = 1/x

so C miles/gallon === 1/(1.609C/3.785) = 3.785/1.609C liters/kilometer

So 30 mpg = 0.0784 liters/kilometer

Which as you can see is very small which is why liters/100 kilometer is more common

So 30 mpg = 7.8 liters/100 kilometer

Banfa 597 Posting Pro Featured Poster

Line 1: strings is not an array of strings it is an array of pointer to char which means...

Line 7: All the entries in strings are pointed to the same buffer, nam

Also k @ lines 7/8 and i @ line 10 are not mentioned anywhere else so we can't tell what value they have and if it is correct.

Assuming k has a good value then if line 9 came after line 10 the code at line 10 could use k too.

val @ line 4 is also not defined anywhere, when posting code it is important to make sure that everything you have posted is defined, and for preference you should post code that can just be copied out of the site into a text file and compiled.

Banfa 597 Posting Pro Featured Poster

When using rundll32. Read the description of this function, if you pass extra parameters on the command line of rundll32 then it passes a pointer to the parameters to the function it is calling.

That means a function called with parameters through rundll32 must take a const char * as its parameter type. Your function takes and int so what is actually being printed in the message box is the value of the pointer to this parameter which is also why it is different every time.

In your own code look at where you call GetProcAddress you have the function name wrong so a NULL pointer is almost certainly being returned. Since you then use the pointer without first checking that it is valid you are getting getting a memory access violation (because you are not allowed to dereference the NULL pointer.

Banfa 597 Posting Pro Featured Poster

This

pNResults.push_back(planetName());

for (i2 = 0; i2 <= cols; i2++)
{
    switch(i2)
    {
    case 1:
        pNResults.at(i).pName = string((char*)sqlite3_column_text(statement,i2));
        break;

    default:
        break;
    }
}

can be written more efficiently as

planetName planet;

if (cols >= 1)
{
    planet.pName = (char*)sqlite3_column_text(statement,1);
}

pNResults.push_back(planet);

it seems to me that the most likely problem is sqlite3_column_text returning NULL and you could modify this to check that

planetName planet;

if (cols >= 1)
{
    const char *data = (char*)sqlite3_column_text(statement,1);

    if (data != NULL)
    {
        planet.pName = data;
    }
    else
    {
        // report error
    }
}

pNResults.push_back(planet);

You should never just assume pointers are good.

If you implemented proper constructors, copy constructors and assignment operators for planetName then there are various other things you can do to simplfy your code.

This

for (i = 0; i < getCount("Planet_Names", bErrors); i++)
{
    ...
}

is very inefficient, every loop iteration you are querying the database store the result of getCount in a variable.

Use the debugger, it will show you where the crash is and by traversing the call stack you should be able to work out where the NULL pointer is.

Banfa 597 Posting Pro Featured Poster

You can do the whole thing as a recursive function without a while loop.

The sudo code would look something like

PrintBinary(Number)
{
    IF Number is 0 Return   // End Case

    Get Least Significant Bit
    Number = Number With Least Significant Bit Removed
    PrintBinary(Number)

    Print Least Significant Bit
}

Because you recurse at line 7 before printing the bit at line 9 you end up actually printing the number most significant bit first even though you are extracting the least significant bits.

All the data that you might normally store in an array or string is held on the stack for you by the function recursion

Banfa 597 Posting Pro Featured Poster

You aren't going to use ifstream or ofstream without including the relevant header. That is what the header is for, to allow you to use the class/declarations.

Banfa 597 Posting Pro Featured Poster

That is one way although there is also a formula for the nth Fibonacci number

Where Phi = the golden ratio = 1.61803398874989484820458683436563811772030917980576

Fib(n) = (pow(Phi, n) - pow(-Phi, -n)) / sqrt(5)

Banfa 597 Posting Pro Featured Poster

You have this wrong

arr[k + width * (j + depth * i)] = l++; //works just fine. perfect.

Compare with your 2D example, in that it is the outer loop variable that is missing from the calculation but that is not the case here. It works only because you have depth == height == width. It should be

arr[k + width * (j + height * i)] = l++; //works just fine. perfect.

This wont work (as you say it can't be right

int** ptr = reinterpret_cast<int**>(&arr[0] + width * i); //this can't be right.
std::cout<<ptr[j][k]; //this line should stay the same.

vmanes solution doesn't work either but only because at line 1 he used int** not int*.

However vmanes solution only has a single index not 2 as you want. The reason that your 2 indexes don't work is because a pointer is not an array and it is absolutely not an array of arrays. int** is still just a pointer don't let the 2 stars confuse you and because it is a pointer all it knows is the size of the object pointed to, int* in this case so the first index moves the pointer on by the size of int* not the size of your virtual array.

You could make this cast work (in theory) like this

int (*ptr)[4] = reinterpret_cast<(*ptr)[4]>(&arr[0] + width * i);
std::cout<<ptr[j][k]; //this line should stay the same.

Instead of using a pointer to …

Banfa 597 Posting Pro Featured Poster

You shouldn't need 2 nested loops, I single for loop should be enough for this.

If you are testing just the last input value then you shouldn't need 3 variables, 2 should be enough.

Is this allowable?
enter a number: 5
enter a number other than 5: 6
enter a number other than 6: 5
enter a number other than 5: 6
etc
Or do you need to test all previously entered numbers? If you do need to test all previously entered numbers your data is not sufficient because you need a way to store all input values.

Finally have you considered what happens if the user enters 0 as there first number?

Banfa 597 Posting Pro Featured Poster

Start with the values 0 and 1 each value in the series is made up by adding the previous 2 values so

0 + 1 = 1
1 + 1 = 2
1 + 2 = 3
2 + 3 = 5
3 + 5 = 8
5 + 8 = 13

Just write a loop that does that, should be easily done with 3 variables.

Then show us your work.

Banfa 597 Posting Pro Featured Poster

Sorry I read this just before home time and didn't have time to reply. I have read up on 10s complement, which appears to be a way to simplify dealing with negatives during addition/subtraction. Fantastic, but you only call it while converting the number to a string.

It sounds like the sort of function that you should call just before doing addition involving negatives or subtraction.

You cannot just take the 10s completement of your initialisation value because you cannot tell the difference between 931, a positive number, and 931, the 3 digit 10s complement of -69 which means that when you do 931 + 931 you can't tell if the result is 1862 (adding 2 positive numbers), 862 (adding a positive and a negative number) or -138 (adding 2 negative numbers requiring the extra step of doing the 10s complement again to convert 862 to -138).

You need to know if the original number was positive or negative and there is no facility for that in you code.

You say you need to be able to cope with 100 digits or more but your code compes with a maximum of 100 digits, I still think a vector is going to help you here to allow you to store any number of digits, when doing addition/subtraction you can always temporarily pad the number with the smaller number of digits to the longer one.

Given all that I probably would not store the number in 10s complement if negative, however that …

Banfa 597 Posting Pro Featured Poster

The problem is your representation of the data (which of course then effects all your code). You have represented the data in the way you think about it as a human not in a way that makes it convienient to process has a computer.

BTW at least at line 26 if you mean the character '0' use the character '0' not the integer 48 because not all environements use the same execution character set and in some character sets the character '0' has a value other than 48.

So for demonstration purposes I am going to assume that NUM_DIGITS is 10

For -739 you hold the string "000000-739"
For -9871 tou hold the string "00000-9871"

You then add them character by character in reverse order and you add the carry at the wrong place, the carry is supposed to be carried over to the next column, you calculate the carry at line 42 and use it at line 47 but you should calculate it at line 42 and use it at line 41 and initialise it to 0 which you do do.

so
9 + 1 = result + carry
3 + 7 = result + carry
7 + 8 = result + carry
7 + 3 = result + carry
('-' - 48) + 9 = result + carry
0 + ('-' - 48) = result + carry
0 + 0 = result + carry
0 + 0 = result …

Banfa 597 Posting Pro Featured Poster

At anytime you think (while programming C++ (or C)) what would work here would be convert all my data to a string so I can interpret it you have made a design error. The computer handles binary data far better than string data the last thing you want to do is hold your data in strings if you can avoid it.

For the example you give with 2 small functions you are far better off using an if statement and then calling the right one of the 2 functions.

The refactoring I suggested in point 4 could be done with a function with the prototype of

int testMatrixCell(int x, int y,
        char cTrazeni,
        int (*Koordinat)[2],
        char cMatrixCellValue,
        int& xStart, int& yStart);
Banfa 597 Posting Pro Featured Poster

He doesn't have any choice but to use that formula, his instructor gave it to him.

Agreed, just don't get me started on instructors that set 1/2 baked questions that lead their students up the garden path :D

Banfa 597 Posting Pro Featured Poster

I am not offended, it is just that putting functions into a header is such an attrociously bad idea that you should avoid doing it in even the smallest project. Either put them in another cpp file if you intend to reuse them in another program or put them in your main.cpp.

Banfa 597 Posting Pro Featured Poster

The issue isn't doing compound interest, it is how the queston originally posted converts from an annual interest rate to an equivilent monthly compound interest rate which is completely wrong.

Banfa 597 Posting Pro Featured Poster

It should be noted that b should also be a floating point number, or alternatively it should be balance in pennies not dollars (or what ever currency you're using).

Also repeatedly doing b = b*(1.0F+(r/1200.0F)); is going to give you compond interest. For example if your starting balance is $1000 and the annual interest rate is 12% (yes only in my dreams) then you might expect at the end of the year to have $1120. However if you add interest using this formula at the end of every month you would get

1.0F + (r/1200.0F) for r = 12 == 1.0F + (12/1200.0F) == 1.0F + (1/100.0F) == 1.01F

bstart = 1000 * 100 = 100000 # in pennies
b1 = 100000 * 1.01F = 101000
b2 = 101000 * 1.01F = 102010
b3 = 102010 * 1.01F = 103030
b4 = 103030 * 1.01F = 104060
b5 = 104060 * 1.01F = 105101 # I choose to round up I'm a nice bank
b6 = 105101 * 1.01F = 106152
b7 = 106152 * 1.01F = 107214
b8 = 107214 * 1.01F = 108286
b9 = 108286 * 1.01F = 109369
b10 = 109369 * 1.01F = 110463
b11 = 110463 * 1.01F = 111568
b12 = 111568 * 1.01F = 112684

Or $1126.84 which is $6.84 greater than you would expect which no bank would ever allow to happen.

If you are doing simple interest then …

Banfa 597 Posting Pro Featured Poster

@COKEDUDE

I would never use fscanf, scanf, sscanf, vfscanf, vscanf, vsscanf or any other scanf derivertive on principle (the principle being they are a nightmare and cause problems and process white space for you). On the other hand I generally try and avoid writing software that has any human interaction since they are just messy and unreliable.

As I said in my original post if you are willing to accept the limitation of a maximum line length then I would fgets to read the lines of text and that would certainly do to start with. If you are unable to live with that limitation then you should write your own function to get a line from a file based given a file identifier based on fgetc (or getc the only difference being that the platform can choose to implement getc as a macro).

If you wanted to future proof yourself you could encapsulate the call to fgets in another function and then if you need to move to a different implementation at a later date you can do it just by changing your function implementation without chantging the rest of the code; e.g.

// Encasulate fgets so that we can change the implentation later if required
char *getLine(FILE* file) // Returns an allocated buffer so remember to free it, returns NULL if end of file
{
#define MAX_LINE_LENGTH 500
  char *buffer;

  buffer = malloc(MAX_LINE_LENGTH);

  if (buffer != NULL)
  {
    char *result = fgets(buffer, MAX_LINE_LENGTH, file);

    // If we got …
Banfa 597 Posting Pro Featured Poster

The way you have written Functions.h is more than something I don't like. The moment you start creating projects with more than 1 cpp file this approach will cause you errors because you will have multiple definitions of all the functions you have put into your header. Headers should only contain declarations it should not contain definitions. A declaration indicates that something exists where as a definition causes something to be brought into existance.

Example

Function declaration

int add(int a, int b);

Function definition

int add(int a, int b)
{
  return a + b;
}

The declaration in a header file included into multiple cpp files will not be a problem, it only states that a function exists, although it would need to exist in one of the cpp files. Put the definition in the header and it exists in all translation units (cpp files) that the header is included into and when you try to link all those translation units together you will get multiple definition errors.

FindStart
Why are you calling this from main and not from FindThePath? The user just wants to find the path they do not want to perform unnecessary initialisation. This function can easily be called from FindThePath, it has all the data, reducing the user to a single function call. Additionally the user does not then need to declare xStart and yStart which they casically have no interest in and if they really need can get from the …

Banfa 597 Posting Pro Featured Poster

You appear to be processing a file that contains a list of 1 line records. In you case the records are simple "<name> <number>" however I would always approch this by reading the entire record before processing it

while(Read Line From File = Success)
{
    Process Line
}

You could use fgets to read the line from the file but this does have the limitation that you need to know your maximum line size ahead of time. Alternatively you could create your own function that reads a line of any size using fgetc.

Again I would write a function to process the line once read spliting the processing of the data from the reading the data from a file. Then if at a later date you need to obtain the data from a different source, say a tcp/ip link, you can still use the same processing function.

Banfa 597 Posting Pro Featured Poster

Also at line 23 else (member !='t'); remove the ;.

Banfa 597 Posting Pro Featured Poster

Well assuming that you don't just want to stick with VB.NET in your position I would go for C# which is also a .NET language so uses the same class library as VB.NET.

Banfa 597 Posting Pro Featured Poster
  • Always use the double type not the float type unless you have a comunicable reason for needing to use float (like it's an embedded platformwithout much memory or the question you are answering specifies use of float).
  • Line 9 for(k=1;k<=n;k++) is poor form, you k is an unsigned type and n happens to be the max value for that type then what you have is an infinite loop. The more normal form to get n iterations is for(k=0;k<n;k++)
  • Line 22 while( (float)p-c>0.01||(float)c-p>0.01) no need to cast c or p to float, they are already floats also you are using math.h so make use of its functions while( fabs(p-c) > 0.01) (fabs returns the absolute value).
  • Line24, similar to 9, for(i=1;i<=j;i++) is poor form. The more normal form to get n iterations is for(i=0;i<j;i++)
  • Line 26 and 27 a=(rand()%10000+1)/1000; doesn't do what you think because it uses integer division. This means you get an integer result between 0 and 10 but I suspect you want a floating point result between 0.001 and 10.000. Since all the types in the formula are integers the compiler does the calculation as integers meaning the /1000 just chops off all the decimal places, if you want it to retain the decimal places you need to force the compiler to use floating point maths. The easiest way is to use floating point constants a=(rand()%10000+1.0F)/1000.0F;. Similarly for line 27. This is the problem as you squew the ration of points in a square to points in …
ddanbe commented: Great. +15
Banfa 597 Posting Pro Featured Poster

Turns out there was a solution however use of a static function provide to be better than a static const object directly

class Example
{
};

class ExampleAccessor
{
public:
  struct _ConstructionFlag
  {
    _ConstructionFlag()
    {
    }

    ~_ConstructionFlag()
    {
    }
  };


  explicit ExampleAccessor(Example&)
  {
  }

  ExampleAccessor(Example&, const _ConstructionFlag&)
  {
  }

  static const _ConstructionFlag& ConstructionFlag()
  {
    static const _ConstructionFlag cf;
    return cf;
  }
};

int main()
{
  Example ex;
  ExampleAccessor accessor(ex, ExampleAccessor::ConstructionFlag());
}
Banfa 597 Posting Pro Featured Poster

Consider this piece of code

class Example
{
};

class ExampleAccessor
{
public:
  struct ConstructionFlag
  {
    ConstructionFlag()
    {
    }

    ~ConstructionFlag()
    {
    }
  };

  explicit ExampleAccessor(Example&)
  {
  }

  ExampleAccessor(Example&, const ConstructionFlag&)
  {
  }
};

int main()
{
  ExampleAccessor accessor(ExampleAccessor::ConstructionFlag());
}

Which is the minimal example of something I found in our code tree today. This compiles without any errors or warnings (on my compilers gcc 4.4 on Linux and mingw 4.5.2 on Windows both C++98). Reading the code I find this to be odd because I would have expected to get a compiler error for a mismatch parameter type while trying constructing an ExampleAccessor object.

It turns out that the compiler actually treats line 30 as a function declaration and produces no code for it.

Anyone else come across this before?
Can we get the compiler to warn/error about this (I tried most of the warning switches I was aware of without effect)
Is there a solution?

Actually I think they answer to the lastq question might be yes use a static const object rather than a temporary.

Banfa 597 Posting Pro Featured Poster

That is rather an opened question but here goes

Line 8 - 12 much more global data than is required, several variables declared global that should be declared local to functions or as function parameters (token, hour, minute, d and f being good examples); d is not used anywhere.

Line 22, 28, 41, 56, 61, 76, 81, 86 All functions declare without a return type, no functions have return statements, no functions use any input parameters so they can't be reused, for example ExtractTimeIn and ExtractTimeOut with no parameters could be a single function ExtractTime taking a const char * (or char *) parameter pointing to the string to extract the time from.

Line 31 and 34 you erroneously have a & infront of the char array variable.

This results is this output from my compiler

test.c: In function 'main':
test.c:17:5: warning: implicit declaration of function 'clrscr'
test.c:18:5: warning: implicit declaration of function 'CreateTimeFile'
test.c:19:5: warning: implicit declaration of function 'GetTimes'
test.c: At top level:
test.c:23:1: warning: return type defaults to 'int'
test.c:28:1: warning: return type defaults to 'int'
test.c: In function 'GetTimes':
test.c:31:5: warning: format '%s' expects type 'char ', but argument 2 has type 'char ()[5]'
test.c:32:5: warning: implicit declaration of function 'ExtractTimeIn'
test.c:34:5: warning: format '%s' expects type 'char ', but argument 2 has type 'char ()[5]'
test.c:35:5: warning: implicit declaration of function 'ExtractTimeOut'
test.c:36:5: warning: implicit declaration of function 'AppendTimes'
test.c: At …

Banfa 597 Posting Pro Featured Poster

Once you have extracted the hours and minutes then check that those numbers are sensible for what they represent.

Banfa 597 Posting Pro Featured Poster

The index may r maynot be needed depending on what type you actually intend timein to have.

There are functions in the C library that will help you convert string to integer, strtol being the one I would use.

Banfa 597 Posting Pro Featured Poster

I do not believe this

char* timein[5], timeout[5], p;

is doing what you think.

It creates

timein as an array of 5 pointers to char (char *)
timeout as an array of 5 char
p as a char.

You should try

char timein[5], timeout[5], *p;

or better still only declare 1 variable per statement then there is no room for confusion

char timein[5];
char timeout[5];
char *p;

Also ValidateTimeIn and ValidateTimeOut have exactly the same structure, if you used an input parameter it could be 1 function.

p is used locally to ValidateTimeIn, ValidateTimeOut and AddToTotalTime and should be declared locally to those functions not globally.

Banfa 597 Posting Pro Featured Poster

It probably is showing you all the spaces it is just that it is using a variable width font and so thoses spaces are not very wide.

Banfa 597 Posting Pro Featured Poster

Line 16, the parameter to Thread is not named.

Line 18, third parameter to _beginthreadex consists of '(__stdcall*) (void *)' which is not a valid anything, perhaps it was meant to be the unnamed function parameter?

Banfa 597 Posting Pro Featured Poster

Code seems to work fine for me except that if there is not a new line at the end of the last number in the list your first loop produces a count that is 1 too small.

Banfa 597 Posting Pro Featured Poster

If you had an extra blank line ((or even a few spaces at the end of the last line) at the end of you dtata file then the !eof end condition in the while loop wouldn't be triggered, however the the request for input in ReadMixedExp would fail.

In this case you would go round the loop again but would fail to read new values for op1 and op2, they stay unchanged and you get an extra line of output.

You should have ReadMixedExp return some sort of status to indicate if the function correctly and then if it fails reading either op1 or op2 end the loop.

P.S. I personally don't really like having to go off to another website I know nothing about to retrieve your source, please put it in the post in future.

Banfa 597 Posting Pro Featured Poster

itemIdInFile is not declared anywhere in the code you have supplied.

Most of your member functions are not declared in the header you supplied.

I surmise that you have not posted your actual code because the code you have posted would not compile and you imply that you can compile it.

Banfa 597 Posting Pro Featured Poster

For many IDEs this is because you are not running the program but debugging it (running it in the debugger). The debugger assumes that you will have added a break point if you want to stop so it doesn't both stopping after program execution.

In stead of debugging the program select the option that actually just runs the program.

Banfa 597 Posting Pro Featured Poster

On line 1 when reading "12.4find" the first time it reads the line it reads the 12.4 and converts it to a float(? or double you don't say) and stores it in f.

The next time round the loop the next thing to read is "find", you request that this be converted to a float (or double) which can't be done. At this point the input stream enters an error state and (inputfile >> f) returns false and the loop stops.

If you want to read a file and handle errors then you would be better off reading each line as a std::string and then reading the value out of the string if you can

Open File

while(get_line_from_file)
{
   put line in stringstream
   read float from stringstream
   if (successful)
   {
     total += float
     count += 1
   }
}
Banfa 597 Posting Pro Featured Poster

So firstly you need to have an idea of what you expect your program to output, you haven't told us so it is rather hard for us to guess.

Secondly if the program is not performing as expected you need to find where the bug is, you could try examining the code but frankly if you haven't already seen it then you are unlikely to spot it now and without having the input data and the expected output I have no clues to go on as to where to look in your code to find an error and I don't care to examine each line of this much code.

That leaves you will tracing through the code to find the problem, you have 2 options here

  1. Us a symbolic debugger, this is a special program, you compile your program in debug mode and run it in the debugger and this allows you to examine the code as it is running including the values of variables and stack trace and memory contents etc.
  2. A poor second is to add additional output (cout) statements to trace the execution path of the program and value of variables. Although a poor second in a small program or localised piece of code this can be plenty.

Things that stand out as errors

  • The implementation of reduce acts only on local unitialised data and does not change the state of the instance it is operating on.
  • in main op1 and op2 are never set
  • in …
Banfa 597 Posting Pro Featured Poster

The problem is everywhere you new Node<TYPE>. The Node<Type> constructor does not set m_NextElement and everywhere you new it you don't set it either so in your list the final element in the list always has an invalid m_NextElement. When calling the list destructor this causes your program to exhibit undefined behaviour (in this case crash probably).

I would add a constructor to Node<Type> that initialised m_NextElement to NULL.

Banfa 597 Posting Pro Featured Poster

Since this is a search not a sort to create an array of pointers to the linked list you will have to iterate over the list and if you are going to do that you may as well just do your search as you do that iteration rather than fill in an array with pointers :D

Banfa 597 Posting Pro Featured Poster

The answer is you probably can't with any efficiency. The thing is to perform an interpolation you have to have random access to your data, that is you need to be able to directly address an member of the data. In a linked list you don't have random access, you have to start with the head or tail pointer.

So for example I would guess your function getIndex returns a member at a given index by starting at the head pointer and moving down the list by the index you are looking for in a loop. I imagine that on average (may be even always) the number of items you iterate through the loop in getIndex is the same or greater than the number of iterations you would make on a straight loop searching for the id instead of trying to do an interpolation.

Interpolations work well on arrays which does have random access or any other contain that has random access.

You equation at line 14 is looks like it is trying to a weighted interpolation (rather than say a binary chop) of the current index (lowest and highest) by the sort parameter (id). However you never change either lowest or highest so it gets middle wrong every time after the first, lowest and highest should probably be altered at lines 20 and 25 respectively.

The if statement line 33 can never be true unless the id supplied was the first id in the list, it would be worth …

Banfa 597 Posting Pro Featured Poster
  1. use a vector not an array

or alternitively

  1. Where you call your functions, example line 32, pass the number of items used in the array rather than the size of the whole array
Banfa 597 Posting Pro Featured Poster

@toneranger, if you have further questions related to this please post them in this thread rather than PM'ing me.

Banfa 597 Posting Pro Featured Poster

I am slightly surprised that you have declared NumericArray as a template I would have expected something similar to

// This is the interface for the derived class
class NumericArray: public Array<double,int>{
...
}

That is the derived class is an implementation of the template for a given type, or even

typedef Array<double,int> NumericArray;

That asside remeber that a template is a pattern it is not actual code it is instructions to the compiler on how to create the code if required. This means that in general the (non-specialised) template must include implementations of all the methods it declares (accept pure virtual ones although I'm not entirely sure of the use case for a pure virtual funciton in a template).

None of the methods in your template Array have any implementations so you will almost always get this error when ever you try to call a method on the template.

When a template class is compiled for a specific type then the compiler creates all the methods that explicitly called or all methods if the template is explicitly instantiated. It compiles all these methods and attaches them to the object for the current file. It then does this with all the code files the template is used in so you get multiple compiled copies of the method. The reason that this doesn't cause a problem for the linker is that they are marked has having weak linkage, this marking means that the linker is able to …

Banfa 597 Posting Pro Featured Poster

It is easiest to understand what << and >> do when you consider a number as a binary value (which is where convertion between binary and decimal come into it). This is because these are bitwise operators (2 of several), that is when they operate they consider individual bits of the operand rather than the overall number.

Considering just << (shift left) the operation is to shift the bits of the left hand operand left by the value of the right hand operand.

Considering the operation 10 << 2 the easiest way to understand what is happening is to consider the decimal value 10 in it's binary form 00001010b (I'm using 8 bits in this illustrantion but there would normally be more).

What happens is that all the digits in the binary representation are shifted (or moved) 2 places in the number to the left

00001010b --> 00001010xxb

The bottom 2 places are filled with 0

00001010xxb --> 0000101000b

And since this is an 8 bit number the top 2 digits are discarded

0000101000b --> 00101000b

And that is the answer converted back to decimal 00101000b = 40

Shift right is similar by the bits are shifted the other way 10 >> 2

Shift each digit 2 places to the right in the number discarding digits that fall off the right hand end

00001010b --> xx000010b

Fill in 0's at the left

xx000010b --> 00000010b

That's you answer the result is 00000010b = 2

The majority of processors have an …

Banfa 597 Posting Pro Featured Poster

How can you tell that program isn't working since it doesn't actually have any output?

Banfa 597 Posting Pro Featured Poster

Use fopen

Banfa 597 Posting Pro Featured Poster

Line 8 initialising b to 0 means that at line 9 you get a divide by zero error while trying to get the remainder after dividing a by b.

Banfa 597 Posting Pro Featured Poster

Get your assignment opertators and constructors correct and copying one to the other becomes a simple std::copy call.

#include <vector>
#include <string>
#include <algorithm>
#include <iterator>

using std::vector;
using std::string;

struct MainStruct
{
public:
    double a;
    double b;
    double c;
    double d;
    unsigned e;
    unsigned f;
    string g;

    MainStruct() :
        a(0.0),
        b(0.0),
        c(0.0),
        d(0.0),
        e(0),
        f(0),
        g()
    {
    }

    MainStruct(const MainStruct&cpy) :
        a(cpy.a),
        b(cpy.b),
        c(cpy.c),
        d(cpy.d),
        e(cpy.e),
        f(cpy.f),
        g(cpy.g)
    {
    }

    const MainStruct& operator= (const MainStruct &cpy)
    {
      if (this != &cpy)
      {
        a=cpy.a;
        b=cpy.b;
        c=cpy.c;
        d=cpy.d;
        e=cpy.e;
        f=cpy.f;
        g=cpy.g;
      }

      return *this;
    }
};

struct MyStruct : MainStruct
{
public:
  string h;

  MyStruct() :
      MainStruct(),
      h()
  {       
  }

  MyStruct(const MyStruct &cpy) :
      MainStruct(cpy),
      h(cpy.h)
  {       
  }

  MyStruct(const MainStruct &other) :
      MainStruct(other),
      h()
  {       
  }

  const MyStruct& operator= (const MainStruct &other)
  {
    MainStruct::operator=(other);
    h="";

    return *this;
  }
};

int main()
{
  vector<MainStruct> OldVec;
  vector<MyStruct> NewVec;

  // Populate OldVec
  OldVec.resize(1000);

  // Clear NewVec if required but in this test program it is already empty

  // Resize NewVec to prevent lots of memory reallocations
  NewVec.reserve(OldVec.size());

  // Copy new to old
  std::copy(OldVec.begin(), OldVec.end(), std::back_inserter(NewVec));

  return 0;
}    

Although this does miss out on the assigning a value to the new string, you could possibly do something with std::transform too which takes an opertor that you let you assign the final parameter (structure definitions as above)

class addIdentity
{
public:
  addIdentity() : id(1)
  {
  }

  MyStruct operator()(const MainStruct& cpy)
  {
    MyStruct newStruct(cpy);
    std::stringstream identifer;

    identifer << "Identifier" << id;
    newStruct.h = …
Banfa 597 Posting Pro Featured Poster

That doesn't fix your problem it hides it. The problem is in your for loop at lines 23, 28, 29, 31 and 32 where you access pArray[s + 1] and names[s + 1]. Since the loop is written for(int s = 0; s < count; s++) in the final iteration s has the value count-1 therefore (s + 1) == count and that means you are accessing the arrays pArray and names outside there bounds which is what is causing your errors.

What you did hide the problem by moving the location in memory used to store pArray, since an out of bounds array access produces undefined behaviour just because the program started working doesn't mean you fixed the problem, just that it no longer showed up as an invalid address access.

When using <LoopCounter>+1 to access arrays you must always be careful that you adjust your loop end condition accordingly so that you do not end up with out of bound array accesses.

BTW you could make your sort more efficient, one of the features of bubble sort is that after each iteration the top (or in your case bottom) item is now correct and no longer needs checking, that means that for each interation of the outer loop of the sort the inner loop can be reduced by 1, your inner loop could be written as for(int s = 0; s < (count - (i + 1)); s++) which would improve the efficiency of the sort and fix …

Banfa 597 Posting Pro Featured Poster

I assume you mean at line 11, that is because operator>> on an istream into a string uses any white space as a separator, it is specifically coded to only read up to the space. If you want to get an entire line into a string use std::getline, declared in string.