Home > Blockchain >  c string subscript out of range/debug assertion failed
c string subscript out of range/debug assertion failed

Time:04-21

I am working on flipping a string of numbers. I get no errors or warnings when compiling, but after I input numbers, there popped out an error window where I can understand none of the words. Can someone help me?

my purpose is:to see, in an interval of numbers, how many numbers have is the same when turned 180 degrees? (e.g.8888, 6699, 90088006)

Enviroment: OS: Windows 10, 64 bit

IDE: Visual studio community 2022

Error window: https://img.codepudding.com/202204/f9f2f51cbbb14dbaaf39786cbd0621b3.png

code:

#include <iostream>
#include <string>

using namespace std;

int total = 0;

void numf(int n, string c) {
    if (!(c.find('3') == 0 and c.find('4') == 0 and c.find('7') == 0 and
          c.find('2') == 0 and c.find('5') == 0)) {

        // reverse
        string c2;

        for (int i = 0; i < sizeof(c) / sizeof(c[0]); i  ) {
            c2[i] = c[sizeof(c) / sizeof(c[0]) - i - 1];
        }
        for (int i = 0; i < sizeof(c) / sizeof(c[0]); i  ) {
            if (c2[i] == '6') {
                c2[i] = '9';
            } else if (c2[i] == '9') {
                c2[i] = '6';
            }
        }
        if (c2 == c) {
            total  ;
        }
    }
    return;
}

int main() {
    int num, num2;

    cin >> num >> num2;

    for (int i = num; i <= num2; i  ) {
        string newnum = to_string(i);
        numf(i, newnum);
    }
    cout << total;
    return 0;
}

CodePudding user response:

For starters this if statement

if (!(c.find('3') == 0 and c.find('4') == 0 and c.find('7') == 0 and
      c.find('2') == 0 and c.find('5') == 0)) {

does not make a sense.

It seems you are trying to exclude numbers that contain one of the listed digits.

In this case you should write

if ( c.find_first_of( "34725" ) == std::string::npos )
{
    //...

The class std::string is not an array. So the expression sizeof(c) / sizeof(c[0]) in the loops like below also does not make a sense.

    for (int i = 0; i < sizeof(c) / sizeof(c[0]); i  ) {
        c2[i] = c[sizeof(c) / sizeof(c[0]) - i - 1];
    }

Moreover the object c2 is empty. So you may not use the subscript operator like c2[i].

You could just write instead of the loop

std::string c2( c.rbegin(), c.rend() );

This incorrect for loop

    for (int i = 0; i < sizeof(c) / sizeof(c[0]); i  ) {
        if (c2[i] == '6') {
            c2[i] = '9';
        } else if (c2[i] == '9') {
            c2[i] = '6';
        }
    }

can be changed for the following range-based for loop

for ( auto &ch : c2 )
{
    if ( ch == '6') 
    {
        ch = '9';
    }
    else if ( ch == '9' ) 
    {
        ch = '6';
    }
}

Pay attention to that the first function parameter is not used within the function.

Also it is a bad idea to use the global variable total within the function. It will be much better if the function had the return type bool and returned true in case when a number satisfies the requirement.

If I have understood the assignment correctly then I would write the program something like the following.

#include <iostream>
#include <string>
#include <utility>
#include <algorithm>

bool numf( const std::string &s )
{
    if ( s.find_first_of( "34725" ) == std::string::npos )
    {
        std::string s2( s.rbegin(), s.rend() );

        for ( auto &c :s2 )
        {
            if (c == '9')
            {
                c = '6';
            }
            else if (c == '6')
            {
                c = '9';
            }
        }

        return s == s2;
    }
    else
    {
        return false;
    }
}

int main()
{
    unsigned int num1 = 0, num2 = 0;

    std::cin >> num1 >> num2;

    std::tie( num1, num2 ) = std::minmax( { num1, num2 } );

    unsigned int total = 0;

    for (; num1 <= num2;   num1)
    {
        total  = numf( std::to_string( num1 ) );
    }

    std::cout << "total = " << total << '\n';
}

The program output might look like

60 99
total = 3

CodePudding user response:

Interesting task you have. Just in case if you're curious about other ways of solving your task, not only about how to fix your code, for that I encoded my own solution for you.

My solution is using small conversion table "01xxxx9x86" for figuring out what will be the 180 degree rotation of a digit, x here signifies that digit is not rotatable.

As you can see I included 1 as rotatable, same as you did in your code, but in some types of font 1 rotated 180 degrees doesn't look same. You may excluded it from rotatables by marking it with x symbol in conversion table of my code.

Try it online!

#include <cstdint>
#include <string>
#include <iostream>

uint64_t RotateCount(uint64_t begin, uint64_t end) {
    uint64_t cnt = 0;
    char constexpr conv[] = "01xxxx9x86";
    for (uint64_t n = begin; n < end;   n) {
        std::string const s = std::to_string(n);
        bool matched = true;
        for (size_t i = 0; i < (s.size()   1) / 2;   i)
            if (conv[s[i] - '0'] != s[s.size() - 1 - i]) {
                matched = false;
                break;
            }
        if (matched)
              cnt;
    }
    return cnt;
}

int main() {
    uint64_t begin = 1'000'000, end = 9'000'000;
    std::cout << "Count: " << RotateCount(begin, end)
        << std::endl;
}

Input range:

1'000'000 ... 9'000'000

Output:

Count: 225

  • Related