Сбор комментариев к john 's answer :
Поскольку значения без знака никогда не меньше 0, вы попадаете в бесконечный цикл, оборачиваясь изаканчивая огромным значением после достижения 0.
Теперь у вас есть несколько вариантов:
Проверить индекс перед уменьшением (юмористический взгляд на это см. здесь ):
for (unsigned long i = add1.length(); i-- > 0; )
Прибыль от обхода поведения при недостаточном потоке:
for (unsigned long i = add1.length() - 1; i < add1.length(); --i)
Обратные итераторы - я бы рассмотрел этонаиболее предпочтительный вариант;но нам нужно инициализировать две переменные и полагаться на оператор последовательности (запятая), некоторые могут отклонить ...:
for(auto i1 = add1.rbegin(), i2 = add2.rbegin(); i1 != add1.rend(); ++i1, ++i2)
// ++, even if going reverse! ^ ^
{
// use *i1 and *i2 here
}
Вы можете предпочесть тип size_t
вместо unsigned long
, он всегда будет иметь соответствующий размер и является типом, который возвращается std::string::length
или функцией size
любого контейнера STL.
Я не вижу, однако, где вы обрабатываете случайadd2
, являющаяся более короткой строкой - любой из приведенного выше приведет к неопределенному поведению!И если add1
является более коротким, вы начинаете где-то в середине add2
.Покрывая оба:
decltype(add1.rend()) ir, er;
for(auto i1 = add1.rbegin(), i2 = add2.rbegin(); ; ++i1, ++i2)
^ leaving out condition!
{
if(i1 == add1.rend())
{
ir = i2; // handle rest of add2 after loop
er = add2.rend(); // needed to be able to compare with appropriate end
break;
}
if(i2 == add2.rend())
{
ir = i1; // handle rest of add1 after loop
er = add1.rend(); // needed to be able to compare with appropriate end
break;
}
// adding the values as you did before
}
for(; ir != er; ++ir)
{
// special handling: append whatever remained from add1 or add2
}
Наконец: stoi(to_string(addN.at(i)))
- я не могу себе представить ничего менее эффективного ...
at
делает проверку диапазона, но через ваш цикл выгарантированный диапазон уже (предполагается, что вы исправили его в соответствии с одним из вариантов выше), поэтому оператор индекса (addN[i]
), который этого не делает, является лучшим выбором.Допустим, на этот раз, поскольку цикл был некорректным, at
не позволил вам неопределенное поведение.Таким образом, вы можете начать с at
сначала и заменить оператором индекса, как только вы узнаете, что код работает правильно ... - (Гораздо тяжелее): промежуточные строки (действительно) имеют длинный путь.Поскольку стандарт C ++ гарантирует, что цифры (только !!!) будут иметь последующие кодовые точки, вы можете просто сделать
addN[i] - '0'
(или *iX - '0'
, если используете итераторы), чтобы получить значение.Если вы хотите оставаться переносимым, не принимайте это также и для букв, как в if('A' <= c && c <= 'Z') c += 'a' - 'A'
(для этого примера уже существует функция , выполняющая то же самое, что вам абсолютно необходимо).
Если мы уже работаем: Если вы добавляете цифры к результирующей строке все новые шифры (ну, код не показан, но я мог бы представить, что вы делаете это ..).) вы будете снова и снова перемещать все уже вставленные значения.Скорее добавьте новые цифры и по завершении примените std::reverse
к результату.