Подтвердить что ты не робот

С++ std:: transform() и toupper().. почему это не удается?

У меня 2 std::string. Я просто хочу, учитывая входную строку:

  • использовать каждую букву
  • присвойте заглавную букву выходной строке.

Как это работает:

  std::string s="hello";
  std::string out;
  std::transform(s.begin(), s.end(), std::back_inserter(out), std::toupper);

но это не так (приводит к сбою программы)?

  std::string s="hello";
  std::string out;
  std::transform(s.begin(), s.end(), out.begin(), std::toupper);

потому что это работает (по крайней мере, в той же строке:

  std::string s="hello";
  std::string out;
  std::transform(s.begin(), s.end(), s.begin(), std::toupper);
4b9b3361

Ответ 1

В out нет пробела. Алгоритмы С++ не вырабатывают целевые контейнеры автоматически. Вы должны либо сделать пространство самостоятельно, либо использовать адаптер вставки.

Чтобы сделать пробел в out, выполните следующее:

out.resize(s.length());

[edit] Другой вариант - создать выходную строку с правильным размером с помощью этого конструктора.

std::string out(s.length(), 'X');

Ответ 2

Я бы сказал, что итератор, возвращенный out.begin(), недействителен после пары приращений для пустой строки. После первого ++ it ==out.end(), тогда поведение после следующего приращения undefined.

В конце концов, это именно то, для чего вставляет итератор.

Ответ 3

Это означает, что он поддерживает: он вставляет элементы в контейнер. используя begin(), вы передаете итератор в пустой контейнер и изменяете недействительные итераторы.

Извините, мои изменения повлияли на ваши комментарии. Я сначала отправил что-то неправильное случайно.