I should reasonably be able to store chars in a std::vector of strings, if the conversion is considered.
Here is the try:
vector<string> f (vector<string> input)
{
vector<string> output;
for (int i=0; i<input.size(); i++) // vector iteration
{
for (int j=0;j<input[i].size(); j++) // string iteration
{
output.push_back(string(input[i].at(j))); // access to characters
}
}
return output;
}
input[i] is a string, and input[i].at(j) is a char; thus, I've converted it to string before pushing to vector<string>.
I'm wondering what's wrong with this approach. Especially, the compiler's error is undecipherable to me:
invalid conversion from '__gnu_cxx::__alloc_traits<std::allocator<char> >::value_type {aka char}' to 'const char*' [-fpermissive]
Edit:
f must work as follows.
Suppose there are 3 strings in the input vector: {abcd,efdr,loab}; then, the output shall extract all atormic characters like: {abcdefdrloab}
To correct your error change
output.push_back(string(&input[i].at(j)));
from
output.push_back(string(input[i].at(j)));
Basically
**for (int i=0; i<input.size(); i++) \\vector iteration**
This is a wrong way of iteration .For containers iterators should be used for iterating
Below copies string from one vector (Use of iterator and stl you can use copy_if or lambda)
#include <iostream>
#include <iterator>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;
vector<string> f (vector<string> input)
{
vector<string> output;
copy(input.begin(),input.end(),back_inserter(output));
return output;
}
int main()
{
vector<string> h{"hello"},x;
x=f(h);
copy(x.begin(),x.end(),ostream_iterator<string>(cout," "));
}
Output
hello Program ended with exit code: 0
But to answer you question and fix of your Code
Below is the modified code
#include <iostream>
#include <iterator>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;
vector<string> f (vector<string> input)
{
vector<string> output;
for (int i=0; i<input.size(); i++)
{
for (int j=0;j<input[i].size(); j++)
{
output.push_back(string(&input[i].at(j)));
}
}
return output;
}
vector<string> fi (vector<string> input)
{
vector<string> output;
copy(input.begin(),input.end(),back_inserter(output));
return output;
}
int main()
{
vector<string> h{"hello"},x,y;
x=fi(h);
y=f(h);
copy(x.begin(),x.end(),ostream_iterator<string>(cout," "));
copy(y.begin(),y.end(),ostream_iterator<string>(cout," "));
}
Output
hello hello ello llo lo o Program ended with exit code: 0
Solution after the edit
#include <iostream>
#include <iterator>
#include<vector>
#include<string>
#include<algorithm>
#include <numeric>
using namespace std;
template<typename T, typename... Args>
void push_back_vec(std::vector<T>& v, Args&&... args)
{
(v.push_back(args), ...);
}
int main()
{
vector<string>x;
push_back_vec(x, "abc", "cds", "ma");
string a = accumulate(x.begin(), x.end(), string(""));
cout<<a;
}
Output
abccdsmaProgram ended with exit code: 0
More easier format
#include <iostream>
#include <iterator>
#include<vector>
#include<string>
#include<algorithm>
#include <numeric>
using namespace std;
int main()
{
vector<string>x{"abc", "cds", "ma"},a;
a.push_back(accumulate(x.begin(), x.end(), string("")));
copy(a.begin(),a.end(),ostream_iterator<string>(cout," "));
}
try this string(1, input[i].at(j))
Related
How to write a program that reads 5 strings from user input and prints only those strings that end with the letter ‘ed’ in C++. Need help!
The solution is rather straightforward.
First we define a container that can contain 5 std::string. For that we use a std::vector together with a constructor to reserve space for the 5 elements.
Then we copy 5 strings from the console (from user input) into the vector.
And, last, we copy elements out of the std::vector to std::cout, if the strings end with "ed".
Because of the simplicity of the program, I cannot explain much more . . .
Please see.
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <iterator>
constexpr size_t NumberOfTexts = 5U;
int main()
{
// Define a container that can hold 5 strings
std::vector<std::string> text(NumberOfTexts);
// Read 5 strings from user
std::copy_n(std::istream_iterator<std::string>(std::cin), NumberOfTexts, text.begin());
// Print the strings with ending "ed" to display
std::copy_if(text.begin(), text.end(), std::ostream_iterator<std::string>(std::cout,"\n"), [](const std::string& s){
return s.size()>=2 && s.substr(s.size()-2) == "ed";
});
return 0;
}
Simple solution,
#include<iostream>
using namespace std;
bool endsWith(const std::string &mainStr, const std::string &toMatch)
{
if(mainStr.size() >= toMatch.size() &&
mainStr.compare(mainStr.size() - toMatch.size(), toMatch.size(), toMatch) == 0)
return true;
else
return false;
}
int main()
{
string s[5];
for(int i=0;i<5;i++)
{
cin>>s[i];
}
for(int i=0;i<5;i++)
{
if(endsWith(s[i],"ed"))
cout<<s[i]<<endl;
}
}
Hope This might Helps:)
I am having what seems to be a common issue however reading through the replies to the similar questions I can't find the solution to my issue at all as I have already done what they are suggesting such as making the variable an array. I have the following code:
#include "stdafx.h"
#include <cstring>
#include <fstream>
#include <iostream>
#include <string>
#include <algorithm>
#include <future>
using namespace std;
string eng2Str[4] = { "money", "politics", "RT", "#"};
int resArr[4];
int main()
{
engine2(eng2Str[4], resArr[4]);
system("Pause");
system("cls");
return 0;
}
void engine2(string &eng2Str, int &resArr)
{
ifstream fin;
fin.open("sampleTweets.csv");
int fcount = 0;
string line;
for (int i = 0; i < 4; i++) {
while (getline(fin, line)) {
if (line.find(eng2Str[i]) != string::npos) {
++fcount;
}
}
resArr[i] = fcount;
}
fin.close();
return;
}
Before you mark as duplicate I have made sure of the following:
The array and variable I am trying to assign are both int
Its an array
The error is:
expression must have pointer-to-object type
The error is occurring at the "resArr[i] = fcount;" line and am not sure why as resArr is an int array and I am trying to assign it a value from another int variable. I am quite new to C++ so any help would be great as I am really stuck!
Thanks!
The problem is that you've declared your function to take a reference to a single string and int, not arrays. It should be:
void engine2(string *eng2Str, int *resArr)
or:
void engine2(string eng2Str[], int resArr[])
Then when you call it, you can give the array names as arguments:
engine2(eng2Str, resArr);
Another problem is the while loop in the function. This will read the entire file during the first iteration of the for() loop. Other iterations will not have anything to read, since it will be at the end of the file already. You could seek back to the beginning of the file, but a better way would be to rearrange the two loops so you just need to read the file once.
while (getline(fin, line)) {
for (int i = 0; i < 4; i++) {
if (line.find(eng2Str[i]) != string::npos) {
resArr[i]++;
}
}
}
I would suggest to use std::vector instead of pure C array.
In your code, there are more issues.
You are passing the fourth element of both arrays to the engine2 function.
From your definition of void engine2(string &eng2Str, int &resArr) you expect reference to a string (not array / vector) and an address / reference of int - you need to pass an pointer to the first element of resArr.
#include <cstring>
#include <fstream>
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <future>
using namespace std;
vector<string> eng2Str = { "money", "politics", "RT", "#" };
int resArr[4] = {};
void engine2(const vector<string>& eng2Str, int* resArr)
{
ifstream fin;
fin.open("sampleTweets.csv");
int fcount = 0;
string line;
for (int i = 0; i < 4; i++)
{
while (getline(fin, line))
{
if (line.find(eng2Str[i]) != string::npos)
{
++fcount;
}
}
resArr[i] = fcount;
}
fin.close();
return;
}
int main()
{
engine2(eng2Str, resArr);
system("Pause");
system("cls");
return 0;
}
Let's say I have an array
string test = {"test1, "test2"}
I have my function
void testing(string test){
for(int i = 0; i < 2; i++){
if(test[i] == "test1"){
cout << "success" << endl;
}
}
}
But when I compile this, I get an error...why is that?
Is there a different approach?
Your test variable should be declared as an array type
string test[] = {"test1", "test2"};
You also need to change the function signature from
void testing(string test)
to
void testing(string* test){
the code you wrote is not going to compile because of wrong declaration of string array.
replace
string test = {"test1, "test2"};
with
string test[]={"test1, "test2"};
The following code uses the array in place without function
#include <iostream>
#include <string>
using namespace std;
string test[]={"test1, "test2"};
for(auto& item:test)
{
cout<<item<<endl;
}
I think the best way to get this working with function is to use vector
#include <iostream>
#include <string>
#include <vector>
using namespace std;
void testing(const vector<string>& strings)
{
for (auto& item : strings)
{
cout << item << endl;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
vector<string> strings = { "str1", "str2", "str3" };
testing(strings);
cin.get();
return 0;
}
I am trying to sort the characters of a string using C++ STL and came up with this code.
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
int main()
{
using namespace std;
vector<string>::iterator it;
string arr[] = {"jajajaj"};
vector<string> v(arr, arr+2);
sort(v.begin(), v.end());
for (it=v.begin(); it<v.end(); it++) {
cout << *it;
}
return 0;
}
But unfortunately its not sorting properly when the array contains single element. How to do it using STL.
Please help.
You can sort the string using std::string class.
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
using namespace std;
int main()
{
string str = "jajajaj";
sort(str.begin(), str.end());
cout << str;
return 0;
}
Hope this might be helpful.
If you need a string, use a std::string :
(I used a for-range loop to make the code cleaner)
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
int main()
{
string s = {"jajajaj"};
sort(s.begin(), s.end());
for (auto c : s)
cout << c;
return 0;
}
Outputs:
aaajjjj
Note:
Your current code is not working because, as commented, you create a vector of size 2 out of an array of size 1, which has undefined behavior.
You seem to be confusing a std::string with an array of chars.
int main()
{
using namespace std;
string arr = "jajajaj";
vector<char> v(arr.begin(), arr.end());
sort(v.begin(), v.end());
vector<char>::iterator it;
for (it=v.begin(); it<v.end(); ++it) {
cout << *it;
}
return 0;
}
I haven't tested that, but it should work....
UPDATE:
Alternately, we could just sort the string's character directly: (Thanks guys!)
int main()
{
using namespace std;
string arr = "jajajaj";
sort(arr.begin(), arr.end());
cout << arr;
return 0;
}
You can use sort() function. sort() exists in algorithm header file
#include<bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
string str = "sharlock";
sort(str.begin(), str.end());
cout<<str<<endl;
return 0;
}
Output:
achklors
In order to sort a string, just input string from the user and use the sort() in STL for it.
#include<bits/stdc++.h>
using namespace std;
int main()
{
string arr;
cin >>arr;
sort(arr.begin(), arr.end());
cout <<arr;
}
See the sample image below for the output with input string as "Michael".
I have a comma separated integers and I want to store them in std::vector<int>. Currently I am manually doing it. Is there any built-in function which did the above functionality?
Edit:
I was in hurry and forget to put full details
Actually i have string (to be exact Unicode string) containing CSvs e.g. "1,2,3,4,5"
Now i want to store them in std::vector<int> so in above case my vector would have five elements pushed into it. Currently i am doing this by manual but its slow as well as there is lot of mess with that code
It's probably not be the most efficient way, but here's a way to do it using the TR1 regex functionality (I also use C++0x lambda syntax in this sample, but obviously it could also be done without that):
#include <iostream>
#include <algorithm>
#include <vector>
#include <regex>
#include <iterator>
#include <cstdlib>
std::vector<int> GetList(const std::wstring &input)
{
std::vector<int> result;
std::wsregex_iterator::regex_type rex(L"(\\d+)(,|$)");
std::wsregex_iterator it(input.begin(), input.end(), rex);
std::transform(it, std::wsregex_iterator(), std::back_inserter(result),
[] (const std::wsregex_iterator::value_type &m)
{ return std::wcstol(m[1].str().c_str(), nullptr, 10); });
return result;
}
You can do this using purely in STL for simplicity (easy to reading, no complex libs needed), which will be fast for coding, but not the fastest in terms of execution speed (though you can probably tweak it a little, like pre-reserving space in the vector:
std::vector<int> GetValues(std::wstring s, wchar_t delim)
{
std::vector<int> v;
std::wstring i;
std::wstringstream ss(s);
while(std::getline(ss,i,delim))
{
std::wstringstream c(i);
int x;
c >> x;
v.push_back(x);
}
return v;
}
(no forwarding(&&) or atoi to keep the code portable).
Sadly, the STL doesn't allow you to split a string on a separator. You can use boost to do it though: (requires a recent C++ compiler such as MSVC 2010 or GCC 4.5)
#include <vector>
#include <string>
#include <algorithm>
#include <iostream>
#include <iterator>
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
using namespace std;
int main(int argc, char** argv)
{
string input = "1,2,3,4";
vector<string> strs;
boost::split(strs, input, boost::is_any_of(","));
vector<int> result;
transform(
strs.begin(), strs.end(), back_inserter(result),
[](const string& s) -> int { return boost::lexical_cast<int>(s); }
);
for (auto i = result.begin(); i != result.end(); ++i)
cout << *i << endl;
}
The quick and dirty option is to use the C string library strtok() function, and atoi():
void Split(char * string, std::vector<int>& intVec)
{
char * pNext = strtok(string, ",");
while (pNext != NULL)
{
intVec.push_back(atoi(pNext));
pNext = strtok(NULL, ",");
}
}
Insert your own input data validation as required.
See:
http://www.cplusplus.com/reference/clibrary/cstring/strtok/
http://www.cplusplus.com/reference/clibrary/cstdlib/atoi/
As well as the wide string versions:
http://msdn.microsoft.com/en-us/library/2c8d19sb%28v=vs.71%29.aspx
http://msdn.microsoft.com/en-us/library/aa273408%28v=vs.60%29.aspx
EDIT:
Note that strtok() will modify your original string, so pass a copy if need be.
Try this:
It will read any type (that can be read with >>) separated by any char (that you choose).
Note: After the object is read there should can only be space between the object and the separator. Thus for things like ObjectSepReader<std::string, ','> it will read a word list separated by ','.
This makes it simple to use our standard algorithms:
#include <vector>
#include <sstream>
#include <iostream>
#include <iterator>
#include <algorithm>
int main()
{
std::stringstream data("1,2,3,4,5,6,7,8,9");
std::vector<int> vdata;
// Read the data from a stream
std::copy(std::istream_iterator<ObjectSepReader<int, ','> >(data),
std::istream_iterator<ObjectSepReader<int, ','> >(),
std::back_inserter(vdata)
);
// Copy data to output for testing
std::copy(vdata.begin(), vdata.end(), std::ostream_iterator<int>(std::cout," "));
}
The secret class to make it work.
template<typename T,char S>
struct ObjectSepReader
{
T value;
operator T const&() const {return value;}
};
template<typename T,char S>
std::istream& operator>>(std::istream& stream, ObjectSepReader<T,S>& data)
{
char terminator;
std::string line;
std::getline(stream, line, S);
std::stringstream linestream(line + ':');
if (!(linestream >> data.value >> terminator) || (linestream.tellg() != line.size()+1) || (terminator != ':'))
{ stream.setstate(std::ios::badbit);
}
return stream;
}
Personally I'd make a structure and have the vector contain instances of the struct.
Like so:
struct ExampleStruct
{
int a;
int b;
int c;
};
vector<ExampleStruct> structVec;
How about this?
#include <string>
#include <vector>
#include <functional>
#include <algorithm>
#include <iostream>
struct PickIntFunc
{
PickIntFunc(std::vector<int>& vecInt): _vecInt(vecInt),_pBegin(0){}
char operator () (const char& aChar)
{
if(aChar == ',' || aChar == 0)
{
_vecInt.push_back(atoi(std::string(_pBegin,&aChar).c_str()));
_pBegin = 0;
}
else
{
if(_pBegin == 0)
{
_pBegin = &aChar;
}
}
return aChar;
}
const char* _pBegin;
std::vector<int>& _vecInt;
};
int _tmain(int argc, _TCHAR* argv[])
{
std::vector<int> vecInt;
char intStr[] = "1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20";
std::for_each(intStr,intStr+sizeof(intStr),PickIntFunc(vecInt));
// Now test it
std::for_each(vecInt.begin(),vecInt.end(), [] (int i) { std::cout << i << std::endl;});
return 0;
}