String[] decode(String message)
Above is an example. I need to get 2 strings s1 and s2 as the return values for the decode function. How should I proceed?
String[] decode(String message)
Above is an example. I need to get 2 strings s1 and s2 as the return values for the decode function. How should I proceed?
If you need return few strings, use one of next:
- std::pair
- boost::tuple
- structure
If you don't know how many strings your function will return - use something like std::vector.
If it were me, I'd return a vector
of string
s. With an array, you'll need to worry about memory management. You could also pass the string in as a const reference, if you don't want to modify it.
If you're feeling hardcore and up for the challenge, you could return a char**.
However, this is very error prone, so you should probably stick to a standard container or string class instead.
Pass the strings to the functions as "out" parameters - either by pointers or references and modify them within the function.
Did they(Top Coder) mentioned array of C-strings or array of std::strings ? For your information, arrays are evil (http://siddhant3s.googlepages.com/how_to_tell_rusted_cpp.html and http://www.parashift.com/c++-faq-lite/containers.html#faq-34.1) Lately, if you still want to return array of std::strings, you can but only if you promise me that you will delete[] the returned pointer accordingly:
#include<iostream>
#include<string>
std::string* F1()
{
std::string* s=new std::string[2];
s[0]="Hello";
s[1]="World";
return s;
}
int main()
{
std::string* ss=F1();
std::cout<<ss[0]<<ss[1];
delete[] ss; //important step
}
I'd say the options are:
For a fixed number of strings:
1) return a pair, a tuple, or a struct that you define yourself. Something like:
struct BrokenDownString {
std::string firstbit;
std::string middlebit;
std::string endbit;
};
Then either:
BrokenDownString decode(std::string message);
or just give BrokenDownString a constructor taking the message as a parameter.
2) Take multiple out params by pointer or non-constant reference:
void decode(const std::string &message, std::string &out_1, std::string &out_2) {
out_1 = /*whatever*/;
out_2 = /*whatever*/;
}
For two strings, anything else (even an array) is overkill.
For a variable number of strings, however, you can either:
1) return a std::vector<std::string>
(be aware that this may result in excess copying).
2) take a std::vector<std::string> &
as a parameter, and append the results (this may copy strings but not the container).
3) make decode a function template, taking an output iterator as a parameter:
template<typename OUT>
void decode(const std::string message, OUT out) {
// do parsing
*(out++) = firstbit;
*(out++) = nextbit;
// etc.
}
Then if the caller wants the results in a vector:
std::vector<std::string> v;
decode(message, std::back_inserter(v));
If the caller prefers them in a deque:
std::deque<std::string> d;
decode(message, std::back_inserter(d));
If the caller wants them in a list in reverse order:
std::list<std::string> l;
decode(message, std::front_inserter(l));
And so on.
4) If you want something like the above, but for whatever reason you don't want to write template code, make decode take as a parameter an object, which it notifies of each string:
struct DecodeTarget {
virtual void append(const std::string &) = 0;
};
void decode(std::string message, DecodeTarget &out) {
// do parsing
out.append(firstbit);
out.append(nextbit);
// etc.
}
Then if the caller wants the results in a vector:
class VectorTarget : public DecodeTarget {
private:
std::vector<std::string> &results;
public:
VectorTarget(std::vector<std::string> &v) : results(v) { }
void append(const std::string &bit) { v.push_back(bit); }
};
std::vector<std::string> v;
VectorTarget vt(v);
decode(message, vt);
If you absolutely must return an array, you can use the fact that raw arrays decay into pointers. Here's some sample code that does what I think you want:
#include <iostream>
#include <ostream>
#include <string>
std::string * decode()
{
std::string *ret = new std::string[2];
ret[0] = "foo";
ret[1] = "bar";
return ret;
}
int main()
{
std::string *baz = decode();
std::cout << baz[0] << baz[1] << std::endl;
delete [] baz;
return 0;
}
Notice that this way requires you to keep track of the following:
decode()
Yes, it's painful. That's why everyone else has suggested using a std::pair
or std::vector
to handle the work for you.