Long Division Output using Vectors of Chars Outputs Garbage
 CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com

Thread: Long Division Output using Vectors of Chars Outputs Garbage

1. Junior Member
Join Date
Jan 2014
Posts
4

Long Division Output using Vectors of Chars Outputs Garbage

Help! This code works very oddly.

Code:
```#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <math.h>
#include <string>
#include <vector>

int isBoolInt(int i)
{
return ((i == 0) || (i == 1));
}

int toVec(std::string inString, std::vector<char>* outVecFinal)
{
if((inString.find_first_not_of("0123456789.") == std::string::npos) && isBoolInt(std::count(inString.begin(), inString.end(), '.')) && (inString != "0") && (inString != "0."))
{
std::vector<char> outVec(inString.begin(), inString.end());
*outVecFinal = outVec;
return 1;
}
else return 0;
}

int vecCheck(std::vector<unsigned short int> vec, unsigned int amount)
{
std::vector<unsigned int> vec2(vec.begin(), vec.begin() + (amount - 1));
std::vector<unsigned int> vec3(vec.begin() + (amount - 1), vec.begin() + ((amount - 1) * 2));
return (vec2 == vec3);
}

int rArrCheck(std::vector<short unsigned int> rArr)
{
int isEqual = 0;

for(unsigned int i = 0; i < rArr.size() / 2 && !isEqual; i++)
isEqual = vecCheck(rArr, i);

return isEqual;
}

double toNum(std::vector<char> vec, bool* negFlag)
{
if(vec.front() == '-')
{
*negFlag = true;
vec.erase(vec.begin());
}

std::string vecString(vec.begin(), vec.end());
double outDouble = 0;
if (vecString.find_first_of(".") == std::string::npos)
outDouble = atof(vecString.c_str());
else
{
std::string strTwo = vecString.substr(vecString.find_first_of(".") + 1, vecString.length() - 1);
outDouble = atof(vecString.substr(0, vecString.find_first_of(".")).c_str());
outDouble += atof( strTwo.c_str() ) / pow( 10, strTwo.length() );
}
return outDouble;
}

double toNum(std::vector<char> vec)
{
std::string vecString(vec.begin(), vec.end());
double outDouble = 0;
if (vecString.find_first_of(".") == std::string::npos)
outDouble = atof(vecString.c_str());
else
{
std::string strTwo = vecString.substr(vecString.find_first_of(".") + 1, vecString.length() - 1);
outDouble = atof(vecString.substr(0, vecString.find_first_of(".")).c_str());
outDouble += atof( strTwo.c_str() ) / pow( 10, strTwo.length() );
}
return outDouble;
}

void longDivide(std::vector<char> dividend, std::vector<char> divisor)
{
std::vector< std::vector<char> > output;

std::vector<char> houseTopV;
for(unsigned int i = 0; i < divisor.size(); i++)
houseTopV.push_back(' ');
for(unsigned int i = 0; i < dividend.size(); i++)
houseTopV.push_back('_');
houseTopV.push_back('_');
output.push_back(houseTopV);

std::string house = std::string(divisor.data(), divisor.size()) + std::string("|") + std::string(dividend.data(), dividend.size());
std::vector<char> houseV(house.begin(), house.end());
output.push_back(houseV);

std::vector<char> divVec;
std::vector<char> lastVec3;
bool* dividendNeg;
*dividendNeg = false;
bool* divisorNeg;
*divisorNeg = false;
toNum(dividend, dividendNeg);
double divisorD = toNum(divisor, divisorNeg);
bool ansNeg = (*dividendNeg != *divisorNeg);
unsigned int indentCount = divisor.size();
divVec.push_back(dividend.at(0));

for(unsigned int i = 0; i < dividend.size(); i++)
{
if((i + 1) < dividend.size())
divVec.push_back(dividend.at(i + 1));

std::vector<char> nextVec;
std::vector<char> nextVec2;
std::vector<char> nextVec3;

for(unsigned int c = 0; c < indentCount; c++)
{
nextVec.push_back(' ');
nextVec2.push_back(' ');
nextVec3.push_back(' ');
}
nextVec3.push_back(' ');

if((toNum(divVec) / divisorD) < 1)
{
nextVec.push_back('-');
nextVec.push_back('0');
nextVec2.push_back('_');
nextVec2.push_back('_');

for(unsigned int j = 0; j < divVec.size(); j++)
nextVec3.push_back(divVec.at(j));

}
output.push_back(nextVec);
output.push_back(nextVec2);
output.push_back(nextVec3);
lastVec3 = nextVec3;
indentCount++;
std::cout << dividend.size() << std::endl;
}

std::cout << std::endl;
for(unsigned int k = 0; k < output.size(); k++)
std::cout << std::string(output.at(k).data(), output.at(k).size()) << std::endl;
}

int main()
{
std::string dividend = "";
std::string divisor = "";
std::vector<char> dividendV;
std::vector<char> divisorV;

std::cout << "Enter a dividend:" << std::endl;
std::cin >> dividend;

while(!toVec(dividend, &dividendV))
{
std::cout << "Enter a dividend again, use at least one nonzero number and nothing but numbers and a decimal point:" << std::endl;
std::cin >> dividend;
}

std::cout << "Enter a divisor:" << std::endl;
std::cin >> divisor;

while(!toVec(divisor, &divisorV))
{
std::cout << "Enter a divisor again, use at least one nonzero number and nothing but numbers and a decimal point:" << std::endl;
std::cin >> divisor;
}

longDivide(dividendV, divisorV);
return 0;
}```

2. Re: Long Division Output using Vectors of Chars Outputs Garbage

Help! This code works very oddly.
Define 'oddly'. What debugging of the code have you done. Where does the program deviate from that expected from the design?

3. Junior Member
Join Date
Jan 2014
Posts
4

Re: Long Division Output using Vectors of Chars Outputs Garbage

The program outputs lots of funny symbols and characters, instead of outputting something like:
___
12|34
-0
__
34
-0
__
34

More functionality will be added soon, but my current code is expected to output the above. Smiley faces, \$, etc. are not an intended output.
I have debugged enough to find that everything works fine, except
Code:
`for(unsigned int i = 0; i < dividend.size(); i++)`
happens too many times, and
Code:
`for(unsigned int j = 0; j < divVec.size(); j++) nextVec3.push_back(divVec.at(j));`
outputs garbage.

4. Junior Member
Join Date
Jan 2014
Posts
4

Re: Long Division Output using Vectors of Chars Outputs Garbage

There should be more spaces in the output. This site seems to have removed them.

5. Re: Long Division Output using Vectors of Chars Outputs Garbage

I have debugged enough to find that everything works fine, except
Code:
`for(unsigned int i = 0; i < dividend.size(); i++)`
happens too many times
Which means that the number of elements in dividend is wrong - so everything is not working fine. So from your debugging, where are the extra element(s) added to the vector dividend?

Code:
`for(unsigned int j = 0; j < divVec.size(); j++) nextVec3.push_back(divVec.at(j));`
outputs garbage.
So divVec doesn't contain the expected data. Again, from your debugging, where is this non-expected data added to the vector?

You need to debug your code tracing through its execution to see where the values of variables, conditions taken etc differ from that which is expected from the design. When you find something changed that was not expected then you have found a possible cause of the problem.

6. Elite Member Power Poster
Join Date
Apr 1999
Posts
27,449

Re: Long Division Output using Vectors of Chars Outputs Garbage

Originally Posted by Users.Random()
The program outputs lots of funny symbols and characters,
1) What is the "toNum" function supposed to perform? If it is to convert a sequence of characters to a number, it looks like you're reinventing the wheel. You have many standard ways of doing this without writing functions. Something as simple as atof() is all you need, and not all of this code you've written to do this job.

Since a vector wraps a contiguous array of characters, you could have just wrapped the function around a call to atof() as so:
Code:
```double toNum(std::vector<char> myVec, bool& isNeg)
{
myVec.push_back(0);  // make sure array is null-terminated
double num = atof(&myVec[0]);  // call function
isNeg = (num < 0)?true:false;  // determine negative
return num;  // return number
}```
This assumes that vec is indeed an array of digits that represents a double.

2) Your parameter passing is all pass-by-value. Nowhere do you pass anything by reference or const reference. This is especially where you're passing vectors by value. This alone can be the source of the problems. Hopefully you're aware of pass-by-value as opposed to pass-by-reference.

In some cases, you can pass by value if you know what you're doing (such as the toNum function I wrote, where the vector will be copied on the passing of the parameter). But in most cases I've seen, passing by value is almost always an oversight or a mistake, unless the parameter is a function object or similar type.

Regards,

Paul McKenzie
Last edited by Paul McKenzie; January 20th, 2014 at 03:29 PM.

7. Junior Member
Join Date
Jan 2014
Posts
4

Re: Long Division Output using Vectors of Chars Outputs Garbage

Issue fixed, it was the way i declared the pointers.

8. Member +
Join Date
Jul 2013
Posts
576

Re: Long Division Output using Vectors of Chars Outputs Garbage

Originally Posted by Users.Random()
Issue fixed, it was the way i declared the pointers.
Avoid pointers in C++.

9. Elite Member Power Poster
Join Date
Apr 1999
Posts
27,449

Re: Long Division Output using Vectors of Chars Outputs Garbage

Originally Posted by Users.Random()
Issue fixed, it was the way i declared the pointers.
Show us your fix, and I can bet your problem isn't really fixed.

Look at this:
Code:
```   bool* dividendNeg;
*dividendNeg = false;
bool* divisorNeg;
*divisorNeg = false;```
You are assigning to an uninitialized pointer. This alone could have crashed your program. If your fix doesn't address this issue, then your program is not really fixed and your program is lucky to even run.

Which takes me back to my original post -- did you see the "isNegative" parameter? It is declared as a reference, not a pointer. Your entire program is devoid of references or passing parameters by reference. There is no need for any pointers in your program whatsoever.

Regards,

Paul McKenzie

10. Re: Long Division Output using Vectors of Chars Outputs Garbage

c++ is not c. Where at all possible in c++, pointers should be avoided. Pointer issues are one of the surest ways to get 'unexplicable' problems when running a program. In a program like this, there is no need to use pointers. Even when a program that uses pointers seems to 'work', there mught still be program problems that just haven't yet surfaced. Some day, on some computer these unknown problems will surface and 'bite'. Take a tip from those of us who have been there, got the teashirt and torn out our hair.

11. Member +
Join Date
Jul 2013
Posts
576

Re: Long Division Output using Vectors of Chars Outputs Garbage

Originally Posted by 2kaud
c++ is not c.
Well, unfortunately it is and that's the problem.

Java and C# don't have this problem. They abandoned C right from the start.

C++ didn't, but in hindsight maybe it is should've.

I mean who needs the C nature of C++ really? It's definately cost C++ a lot.
Last edited by razzle; January 20th, 2014 at 07:11 PM.

12. Elite Member Power Poster
Join Date
Nov 2003
Location
Florida
Posts
12,518

Re: Long Division Output using Vectors of Chars Outputs Garbage

Pointers can be a bit tricky at first and they can be a bit dangerous, but advising to completely avoid them seems a bit over the top, and in many cases pretty much impossible.

13. Elite Member Power Poster
Join Date
Jan 2006
Location
Singapore
Posts
6,736

Re: Long Division Output using Vectors of Chars Outputs Garbage

Originally Posted by razzle
I mean who needs the C nature of C++ really? It's definately cost C++ a lot.
I have not read The Design and Evolution of C++, but the impression I get from Stroustrup's brief FAQ answer to Why did you make C++ (almost) compatible with C? is that Stroustrup needed the C nature of C++ early on to ensure its suitability for systems programming. Personally, I think it was a reasonable idea even in retrospect as it allows for C libraries to be more directly available for C++ programmers, at the cost of the warts that come along with C.

Furthermore, I suspect that C's popularity played a considerable part in boosting C++'s popularity as well. Then again, we don't actually need C++ to be popular to program in C++

14. Senior Member
Join Date
Oct 2008
Posts
1,456

Re: Long Division Output using Vectors of Chars Outputs Garbage

a C++ incompatible with C ? oh my ! it would have been a total disaster ... C is a great language for low level programming with portable and easy to code compilers/libraries/ABIs... and it's a blessing that C++ is compatible with it ( at least, with a sufficiently big subset of it to be able of effortlessly interfacing with C libraries/bindings; indeed, c and c++ are not compatible at all in other respects, just consider foundamental differences like the lvalueness of assignments ... ).

Sure, pointers are dangerous, but they're not so because there exists an obscure force compelling programmers to misuse them ( bad programmers do, but bad programmers can misuse anything by definition ), they're dangerous because they lack semantics. For example, a recent proposal for standardization was a new "smart" pointer, the "exempt_ptr", whose only purpose is to document that that pointer is just "observing" some data and nothing more, being totally equivalent to a naked pointer in other respects.
Last edited by superbonzo; January 21st, 2014 at 05:11 AM. Reason: typo

15. Re: Long Division Output using Vectors of Chars Outputs Garbage

c++ is not c.
To clarify, I meant that the way you programmed in c++ is not necessarily the way you would program in c. Yes, you can use c++ like you would c but its not recommended.

Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•