Как я могу объединить элементы вектора целых чисел в строку на С++?

Я пытался поместить каждый элемент вектора целых чисел в строку. Я хочу добиться этого путем преобразования целых чисел в строки, после чего я объединяю эти «маленькие строки» в одну большую строку, которая будет представлять все элементы этого конкретного вектора.

Это может выглядеть глупо, но действительно полезно, если вы хотите создать функцию, которая возвращает вектор, подобный чему-то, и т. д.

Единственная проблема в том, что я получаю сообщение об ошибке в строке 13, в которой говорится:

error: no matching function for call to ‘std::__cxx11::basic_string<char>::basic_string(int&)’
   13 |     myString += (string) myVector[i];
      |                                    ^

и я не имею ни малейшего представления о том, почему это происходит. Мой код следует ниже:

#include <iostream>
#include <vector>
using namespace std;

int main()
{
  int myVector[5] = {1,2,3,4,5};

  string myString = "";

  for (int i =0; i < 5; i++)
  {
    myString += (string) myVector[i];
    myString += "\n";
  }

  cout << myString << endl;

Любая помощь будет высоко ценится.

std::ostringstream , std::ostream_iterator и std::copy. И если вы просто собираетесь печатать значения, то пропустите поток строк и используйте std::cout напрямую.
Some programmer dude 30.01.2023 15:00

И в качестве общего совета: всякий раз, когда вы чувствуете необходимость выполнить приведение в стиле C (например, при попытке преобразовать целое число в строку), вы должны рассматривать это как признак того, что вы делаете что-то неправильно.

Some programmer dude 30.01.2023 15:03

и я не имею ни малейшего представления о том, почему это происходит. Возможно, вы привыкли к другим языкам, которые выполняют такой тип преобразования целого числа в строку, где все, что вам нужно сделать, это иметь + и волшебным образом целое превратится в строку? Если да, то вы видите, что C++ так не работает.

PaulMcKenzie 30.01.2023 15:07

в общем, найти все возможные преобразования непросто, найти отсутствие преобразования еще сложнее, но неплохо начать с конструкторов std::stringen.cppreference.com/w/cpp/string/basic_string/basic_string

463035818_is_not_a_number 30.01.2023 15:10
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
4
117
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

Ответ принят как подходящий

Вы можете использовать std::to_string для преобразования int в std::string.

Измените эту строку:

myString += (string) myVector[i];

К:

myString += std::to_string(myVector[i]);

Примечание: подобное объединение строк может быть не столь эффективным из-за создания и уничтожения временных строк (хотя вполне вероятно, что сработает оптимизация небольших строк, поэтому дополнительных выделений кучи не будет).
Как прокомментировал @Someprogrammerdude, вы можете использовать std::ostringstream.

Боковые примечания:

  1. Тебя не хватает #include <string>.
  2. Почему "используя пространство имен std;" считается плохой практикой?.

создается и уничтожается много временных строк. Из-за SSO вряд ли произойдет выделение кучи.

Evg 30.01.2023 15:28

@Evg разъяснил этот момент.

wohlstad 30.01.2023 15:34

Вы можете использовать std::stringstream

#include <iostream>
#include <string>
#include <sstream>
int main()
{
    int myVector[5] = {1,2,3,4,5};
    std::string myString;

    std::stringstream sstream;
    for (auto i : myVector)
        sstream << i;

    sstream >> myString;
    std::cout << myString;
}

Ссылка.

Перегрузите оператор потока вывода, и тогда у вас будет что-то, что можно использовать повторно во многих сценариях.

Основываясь на приведенных ниже отзывах, перегрузка - не лучший ответ, другой подход здесь: https://www.onlinegdb.com/zDUjVbSTp

#include <vector>
#include <iostream>
#include <string>
#include <sstream>

// Overloading operator<< will have many benefits.
// you can use it to output an array to std::cout directly
// or you can write it to a file or stringstream
std::ostream& operator<<(std::ostream& os, const std::vector<int>& values)
{
    os << "[";
    bool comma = false;
    for (const auto& value : values)
    {
        if (comma) os << ", ";
        os << value;
        comma = true;
    }
    os << "]";

    return os;
}

int main()
{
    std::vector<int> values{ 1,2,3,4,5 }; 

    // write directly to std::cout
    std::cout << "direct : " << values << "\n";

    // adding array to a string
    std::ostringstream os;
    std::string string{ "output = " };
    os << values;
    string += os.str();
    std::cout << string << "\n";
    

    return 0;
}

Я бы не стал перегружать операторы для стандартных типов. Предположим, вы используете библиотеку, которая также предоставляет такую ​​перегрузку, и другую, которая делает то же самое...

463035818_is_not_a_number 30.01.2023 15:12

Это справедливое замечание

Pepijn Kramer 30.01.2023 15:16

Перегрузка operator<< имеет смысл для типов, для которых у вас есть более или менее канонический формат вывода, например целые числа или строки. Для таких типов, как std::vector<T>, это сомнительно, потому что не существует канонического вывода — можно использовать пробелы или запятые в качестве разделителей, помещать или не заключать всю последовательность в скобки и т. д.

Evg 30.01.2023 15:16

между прочим, именованная функция void print(std::ostream& out,const std::vector<int>&) имеет те же преимущества, которые вы перечисляете.

463035818_is_not_a_number 30.01.2023 15:18

@463035818_is_not_a_number Да я и сейчас это понимаю :) onlinegdb.com/zDUjVbSTp

Pepijn Kramer 30.01.2023 15:25

Я оставлю этот ответ как есть, так как я думаю, что он содержит полезную информацию и для других :)

Pepijn Kramer 30.01.2023 15:26

Вы можете использовать библиотеку fmt:

  1. fmt::join примет диапазон, в вашем случае вектор целых чисел, и соединит его содержимое с заданным разделителем (например, пустую строку, если вы просто хотите, чтобы все элементы были вместе).
  2. fmt::format создаст строку с заданным форматом, в данном случае только содержимое объединенного вектора.

Демо

#include <fmt/ranges.h>

int main() {
  int myVector[5] = {1,2,3,4,5};
  auto myString = fmt::format("{}", fmt::join(myVector, ""));
  fmt::print("{}\n", myString);
}

// Outputs: 12345

Или, проще, если вам не нужна строка:

int main() {
  int myVector[5] = {1,2,3,4,5};
  fmt::print("{}\n", fmt::join(myVector, ""));
}

Ошибка, которую вы получаете, говорит о том, что компилятор не может найти функцию std::__cxx11::basic_string<char>::basic_string(int&), то есть конструктор std::string, принимающий int&.

Я добавлю свое собственное решение, как указано в моем комментарии:

#include <iostream>
#include <iterator>
#include <algorithm>
#include <vector>

int main()
{
    std::vector myvector = { 1, 2, 3, 4, 5 };

    std::copy(std::begin(myvector), std::end(myvector),
              std::ostream_iterator<int>(std::cout, "\n"));
}

Вы также можете использовать алгоритм for_each для конкатенации.

#include <iostream>
#include <algorithm>

int main()
{
    std::vector<int> v{1, 2, 3, 4, 5, 6};  

    std::string all;
    std::for_each(v.begin(), v.end(), [&, del = ""](const int &e) { 
        all += std::to_string(e) + (&e == &v.back() ? "" : del); 
    });
    std::cout << all << std::endl;
}

выход:

123456

Если вы хотите добавить разделитель между ними, просто измените значение del в лямбда-захвате.

std::for_each(v.begin(), v.end(), [&, del = "-"](const int &e) { 
        all += std::to_string(e) + (&e == &v.back() ? "" : del); 
    });

Выход:

1-2-3-4-5-6

Другие вопросы по теме