add each int in a vector<int> to a string - c++

for (vector<int>::const_iterator i = vec.begin(); i != vec.end(); ++i)
{
int number = *i;
char* c;
itoa(number, c, 10);
result += c;
}
std::cout << result << std::endl;
I'm trying to convert each int in "vec" to a char and adding it to a string but I just get a compiler error. what am I doing wrong?

You can use the std::to_string available in C++11:
#include <iostream>
#include <vector>
#include <string>
int main()
{
std::vector<int> vec;
for (int i = 0; i < 100; i++)
{
vec.push_back(i);
}
std::string result;
for (std::vector<int>::const_iterator i = vec.begin(); i != vec.end(); ++i)
{
result += std::to_string(*i);
}
std::cout << result << std::endl;
}

Combining sounds like a job for std::accumulate.
#include <iostream>
#include <numeric>
#include <string>
#include <vector>
auto main() -> int
{
const std::vector<int> vec{ 1, 2, 3 };
const std::string result = std::accumulate(vec.begin(), vec.end(), std::string(),
[](const std::string& s, const int value)
{
return s + std::to_string(value);
});
std::cout << result << std::endl;
}

There's an error in your code:
You call itoa() with a non-initialized char pointer. That's bad, because itoa() needs a valid buffer! Besides, itoa() is not part of the c++ standard.
Better do leave char* behind and do it with more modern C++ features, especially std::stringstream, which is a string builder, which is powerful in conversion (and also often faster than the string += operator). It builds a string by pushing elements to it with the << operator (these can be string literals, strings, numbers of all kinds), it can be extended via external operators for own data types, and it also has a lot of formatting options (e.g. number of digits, hex etc), and returns its built string with the method str().
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
int main()
{
std::vector<int> vec;
for (int i = 0;i<100;i++)
vec.push_back(i);
std::stringstream ss;
for (auto& number : vec)
ss << number;
std::cout << ss.str() << std::endl;
}

Related

How can I concatenate the elements of a vector of integers to a string in C++?

I've been trying to put every single element of a vector of integers into a string. I want to achieve this by type casting the integers into strings, after that I cocatenate those "small strings" into a single big string, which is going to represent all the elements of that specific vector.
This may look silly, but is really useful if you want to make a function that returns a vector like-a-thing, or etc.
The only problem is that I'm getting an error on line 13, which says :
error: no matching function for call to ‘std::__cxx11::basic_string<char>::basic_string(int&)’
13 | myString += (string) myVector[i];
| ^
and I don't have the slightest idea on why this is happening. My code follows below :
#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;
any help will be much appreciated.
You can use std::to_string to convert an int to a std::string.
Change this line:
myString += (string) myVector[i];
To:
myString += std::to_string(myVector[i]);
Note: concatenating strings like that might not be so efficient due to temporary strings being created and destroyed (although it is likely that small strings optimization will kick in, so no additional heap allocations will take place).
As #Someprogrammerdude commented, you can consider to use std::ostringstream.
Side notes:
You are missing #include <string>.
Why is "using namespace std;" considered bad practice?.
You can use the fmt library:
fmt::join will accept a range, in your case a vector of ints, and join its contents with a given separator (e.g. an empty string if you just want all of the elements together).
fmt::format will create a string with a given format, in this case just the contents of the joined vector.
Demo
#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
Or, simpler, if you don't need the string:
int main() {
int myVector[5] = {1,2,3,4,5};
fmt::print("{}\n", fmt::join(myVector, ""));
}
The error you are getting is saying that the compiler cannot find a std::__cxx11::basic_string<char>::basic_string(int&) function, i.e., a std::string constructor accepting an int&.
You can use 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;
}
Link.
I'll add my own solution, as laid out in my comment:
#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"));
}
Overload the output stream operator, and then you have something reusable for a lot of scenarios.
Based on the feedback below overloading is not the best answer, another approach here : 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;
}
You can use for_each algorithm as well to do the concatenation.
#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;
}
output:
123456
If you want to add a delimiter in between, just change the del value in lambda capture.
std::for_each(v.begin(), v.end(), [&, del="-"](const int &e) {
all += std::to_string(e) + (&e == &v.back() ? "" : del);
});
Output:
1-2-3-4-5-6

Build incremental std::string

I try to build an std::string in the form of "start:Pdc1;Pdc2;Pdc3;"
With following code I can build the repeated "Pdc" and the incremental string "123" but I'm unable to combine the two strings.
#include <string>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <iterator>
#include <numeric>
int main()
{
std::ostringstream ss;
std::string hdr("start:");
std::fill_n(std::ostream_iterator<std::string>(ss), 3, "Pdc;");
hdr.append(ss.str());
std::string v("abc");
std::iota(v.begin(), v.end(), '1');
std::cout << hdr << std::endl;
std::cout << v << std::endl;
std::cout << "Expected output: start:Pdc1;Pdc2;Pdc3;" << std::endl;
return 0;
}
How can I build this string? Preferable without a while or for loop.
The expected output is: start:Pdc1;Pdc2;Pdc3;
std::strings can be concatenated via their operator+ (or +=) and integers can be converted via std::to_string:
std::string res("start:");
for (int i=0;i<3;++i){
res += "Pdc" + std::to_string(i+1) + ";";
}
std::cout << res << "\n";
If you like you can use an algorithm instead of the handwritten loop, but it will still be a loop (your code has 2 loops, but only 1 is needed).
Code to generate your expected string, though with a small for loop.
#include <iostream>
#include <string>
#include <sstream>
std::string cmd(const std::size_t N)
{
std::ostringstream os;
os << "start:";
for(std::size_t n = 1; n <= N; ++n) os << "Pdc" << n << ";";
return os.str();
}
int main()
{
std::cout << cmd(3ul);
return 0;
}

Reverse For loop Crashes

So I have this code and it crashes xcode
void strrev(const std::string& str)
{
for(size_t i=str.length();i>=0;i--)
{
std::cout << str[i];
}
}
It works fine if I do i>0 but then the first character does not get printed
Any suggestions on what is wrong with i>=0 ?
Problem
i is of type size_t (it is an unsigned integral), so when i is zero and i-- is performed, its value wraps around, getting i the highest possible value it can store. This i is then used in the expression str[i] causing a crash.
Solution
You can separately handle the case for i equal to zero. Also, since indices start at zero, the highest possible index is str.length()-1.
It should be then:
for(size_t i=str.length()-1; i > 0; i--)
std::cout << str[i];
std::cout << str[0];
Recommended alternatives
Consider using reverse iterators instead to avoid having to deal with indices:
void strrev(const std::string& str)
{
for (auto rit = str.rbegin(); rit != str.rend(); ++rit)
std::cout << *rit;
}
Note that you can also use std::copy in combination with reverse iterators and a std::ostream_iterator object for std::cout:
#include <iostream>
#include <algorithm>
#include <string>
#include <iterator>
void strrev(const std::string& str)
{
std::copy(str.rbegin(), str.rend(),
std::ostream_iterator<std::string::value_type>{std::cout});
}
or directly use std::reverse_copy instead of std::copy and therefore no need for reverse iterators:
std::reverse_copy(str.begin(), str.end(),
std::ostream_iterator<std::string::value_type>{std::cout});
It's better to do this in an idiomatic, index-free way using std::reverse.
#include <algorithm>
#include <iostream>
#include <string>
int main() {
std::string str = "Hello World!";
std::reverse(str.begin(), str.end());
std::cout << str << "\n"; // !dlroW olleH
}
Since the strings in c++ are base zero -the first character in a string is str[0]- therefor the index of the last character in a c++ string is always str.length()-1 or str.size()-1
So it should be
void strrev(const std::string& str)
{
for(size_t i=str.length()-1;i>=0;i--)
{
std::cout << str[i];
}
}

Limiting decimal places of a float when converting to string in C++

I'm making a function which prints the elements of a std::vector<float>.
Working code:
std::vector<float> components { 1, 2, 3 };
string result = "<";
for ( auto it = begin(this->components); it != end(this->components); ++it ) {
result.append(to_string(*it));
if (it != (this->components))
result.append(", ");
}
result.append(">");
std::cout << result;
The intended result is if "components" has elements 1,2,3, for example, it will print: <1, 2, 3>.
Right now it is printing the numbers as floats, of course, like < 1.000000, 2.000000, 3.000000, >.
Is there a way I can control how many decimal places are put into the string, without having to manually go through it character by character?
As a side note, how do I prevent it from adding a ',' after the last element?
You may use std::stringstream.precision for that.
Just create a std::stringstream convert it to a string and your done.
Like so:
stringstream ss;
ss.precision(3);
ss << "<";
for ( auto it = begin(this->components); it != end(this->components); ++it ) {
ss << *it;
if (it != (this->components))
ss << ", ";
}
ss << ">";
string result = ss.str();
you can use sprintf() before casting:
float a = 1.000000;
char aa[20];
sprintf(aa, "%1.3f", a);
Here is the complete code which i ran:
#include <vector>
#include <iterator>
#include <iostream>
using namespace std;
int main()
{
std::vector<float> components{ 1, 2, 3 };
string result = "<";
for (auto it = components.begin(); it != components.end(); ++it) {
float a = *it;
char aa[20];
sprintf(aa, "%1.3f", a);
result.append(string(aa));
if (it+1 != components.end())
result.append(", ");
}
result.append(">");
std::cout << result.c_str();
getchar();
return 0;
}
Output:
I would do it like this using a stringstream.
#include <iostream>
#include <sstream>
#include <iomanip>
#include <vector>
int main()
{
std::vector<float> components {1, 2, 3, 1.5f, 2.5f, 3.5f, 1.25f, 2.25f, 3.25f, 1.12345f};
std::stringstream result;
result << "<";
for(auto it = std::begin(components); it != std::end(components); ++it)
{
if(it != std::begin(components))
{
result << ", ";
}
result << *it;
}
result << ">";
std::cout << result.str();
return 0;
}
You could also use std::fixed and std::setprecision to modify the output further as you desire.
Printing the comma before the next item for all but the first item fixes your trailing comma issue.
Here's a demo of it working:
As #Axalo already noted, you can use setprecision with an ostream to set its precision (and it can be used with any ostream, not just cout).
To eliminate the trailing comma, I'd probably use the infix iterator I've posted elsewhere.
Using that, the code could be written something like this:
#include <iostream>
#include <sstream>
#include <vector>
#include <iomanip>
#include "infix_iterator.h"
int main () {
// Data that would display extra precision if we didn't stop it
std::vector<float> components { 1.123f, 2.234f, 3.345f };
std::ostringstream buff("<", std::ios::app);
buff << std::setprecision(2);
std::copy(components.begin(), components.end(),
infix_ostream_iterator<float>(buff, ", "));
buff << ">";
std::cout << buff.str();
}
Result: <1.1, 2.2, 3.3>

C++ sort array of strings

I am trying to sort an array of strings, but it's not sorting anything.... what am I doing wrong?
string namesS[MAX_NAMES];
int compare (const void * a, const void * b){
return ( *(char*)a - *(char*)b );
}
void sortNames(){
qsort(namesS, MAX_NAMES, sizeof(string), compare);
}
This is C++, not C. Sorting an array of strings is easy.
#include <string>
#include <vector>
#include <algorithm>
std::vector<std::string> stringarray;
std::sort(stringarray.begin(), stringarray.end());
std::qsort is inherited from the standard C library. It will not work.
You need to use std::sort for sorting strings.
Specifically, cast std::string to void* and then to char* is undefined and won't work.
algorithm sort in CPP has the same complexity as qsort:
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
using namespace std;
bool compare(string a, string b){
cout << "compare(" << a << "," << b << ")" << endl;
return (a.compare(b) < 0);
}
int main () {
string mystrs[] = {"www","ggg","bbb","ssss","aaa"};
vector<string> myvector (mystrs, mystrs + 5);
vector<string>::iterator it;
sort (myvector.begin(), myvector.end(), compare);
cout << "vector contains:";
for (it=myvector.begin(); it!=myvector.end(); ++it)
cout << " " << *it;
cout << endl;
return 0;
}
You can use boost::sort, like this:
#include <vector>
#include <boost/range/algorithm.hpp>
std::vector<std::string> stringarray;
boost::sort(stringarray);
If you want use find use boost::find, like this:
std::string findme;
auto offset = boost::find(stringarray, findme) - stringarray.begin()
See 2 useful functions (m_stringarray should be member of ClassA):
const size_t ClassA::GetIdByName(std::string name) const
{
return (boost::find(this->m_stringarray, name) - this->m_stringarray.begin());
}
const std::string ClassA::GetNameById(size_t id) const
{
return this->m_stringarray[id];
}
As many here have stated, you could use std::sort to sort, but what is going to happen when you, for instance, want to sort from z-a? This code may be useful
bool cmp(string a, string b)
{
if(a.compare(b) > 0)
return true;
else
return false;
}
int main()
{
string words[] = {"this", "a", "test", "is"};
int length = sizeof(words) / sizeof(string);
sort(words, words + length, cmp);
for(int i = 0; i < length; i++)
cout << words[i] << " ";
cout << endl;
// output will be: this test is a
}
If you want to reverse the order of sorting just modify the sign in the cmp function.
Here is C++ another way to sort array of string without using <vector>.
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
string WordArray[] = {"AA","DD","CC","BB","ZZ","NN"};
sort(begin(WordArray), end(WordArray)); /*Sort the Array*/
for(auto& Word: WordArray){
cout<<Word<<endl; /*Print Every String Element*/
}
return 0;
}