Long Division Output using Vectors of Chars Outputs Garbage
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 16

Thread: Long Division Output using Vectors of Chars Outputs Garbage

  1. #1
    Join Date
    Jan 2014
    Posts
    4

    Post 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> answer;
    
        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;
        }
        //output.insert(output.begin(), answer.begin(), answer.end());
    
        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. #2
    Join Date
    Dec 2012
    Location
    England
    Posts
    2,266

    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?
    All advice is offered in good faith only. You are ultimately responsible for effects of your programs and the integrity of the machines they run on.

  3. #3
    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. #4
    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. #5
    Join Date
    Dec 2012
    Location
    England
    Posts
    2,266

    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.
    All advice is offered in good faith only. You are ultimately responsible for effects of your programs and the integrity of the machines they run on.

  6. #6
    Join Date
    Apr 1999
    Posts
    27,423

    Re: Long Division Output using Vectors of Chars Outputs Garbage

    Quote Originally Posted by Users.Random() View Post
    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. #7
    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. #8
    Join Date
    Jul 2013
    Posts
    213

    Re: Long Division Output using Vectors of Chars Outputs Garbage

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

  9. #9
    Join Date
    Apr 1999
    Posts
    27,423

    Re: Long Division Output using Vectors of Chars Outputs Garbage

    Quote Originally Posted by Users.Random() View Post
    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. #10
    Join Date
    Dec 2012
    Location
    England
    Posts
    2,266

    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.
    All advice is offered in good faith only. You are ultimately responsible for effects of your programs and the integrity of the machines they run on.

  11. #11
    Join Date
    Jul 2013
    Posts
    213

    Re: Long Division Output using Vectors of Chars Outputs Garbage

    Quote Originally Posted by 2kaud View Post
    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. #12
    GCDEF is offline Elite Member Power Poster
    Join Date
    Nov 2003
    Posts
    12,055

    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. #13
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,247

    Re: Long Division Output using Vectors of Chars Outputs Garbage

    Quote 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++
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  14. #14
    Join Date
    Oct 2008
    Posts
    1,088

    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. #15
    Join Date
    Dec 2012
    Location
    England
    Posts
    2,266

    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.
    All advice is offered in good faith only. You are ultimately responsible for effects of your programs and the integrity of the machines they run on.

Page 1 of 2 12 LastLast

Posting Permissions

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


Azure Activities Information Page

Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center