I know how to add integers to strings, but I'm not sure I'm doing it in an efficient matters. I have a class where I often have to return a string plus an integer (a different integer each time), in Java I would do something like
public class MyClass {
final static String S = "MYSTRING";
private int id = 0;
public String getString() {
return S + (id++);
}
}
But in C++ I have to do;
class MyClass {
private:
std::string S; // For some reason I can't do const std::string S = "MYSTRING";
int id;
public:
MyClass() {
S = "MYSTRING";
id = 0;
}
std::string getString() {
std::ostringstream oss;
oss << S << id++;
return oss.str();
}
}
An additional constraint: I don't want (in fact, in can't) use Boost or any other librairies, I'll have to work with the standard library.
So the thing is; the code works, but in C++ I have to create a bunch of ostringstream objects, so it seems inefficient. To be fair, perhaps Java do the same and I just don't notice it, I say it's inefficient mostly because I know very little about strings.
Is there a more efficient way to do this ?
std::ostringstream is the "standard" way to do this in C++. You might be able to make something more efficient via some custom coding, or laboriously comparing the performance of ostringstream, itoa, and sprintf on all the systems where you'll be deploying this program, but it's probably not worth the effort.
I'd say the real problem with the std::ostringstream solution is not about efficiency. The real problem is that the code just looks too complicated.
I know you don't want to use Boost, but if you look at Herb Sutter's The String Formatters of Manor Farm, you could just copy the (very tiny) definition of the lexical_cast<>() template into your program. Then your code would look like this:
std::string getString() {
return S + lexical_cast<std::string>(id++);
}
Whether this is more efficient than your existing solution depends on a lot of factors (how well your compiler inlines template instantiations, for example), but it definitely looks cleaner.
I'm pretty sure you can do the following:
class MyClass
{
private:
const std::string S; // For some reason I can't do const std::string S = "MYSTRING";
int id;
public:
MyClass() :
S( "MYSTRING" )
{
id = 0;
}
}
Thats totally off the top of my head and untested though so I'm fully expecting tonnes of down votes :D hehehe
To add to the other answers:
... the code works, but in C++ I have to create a bunch of ostringstream objects, so it seems inefficient. To be fair, perhaps Java do the same and I just don't notice it, ...
Java does in fact do exactly the same thing; + with Strings is syntactic sugar for StringBuffer.append(), so these do the same thing:
String f = "foo";
f += "bar" + "baz";
String f = "foo";
f = StringBuffer(f).append("bar").append("baz");
You are right, ostringstream generally add overhead.
This is more efficient, and IMO is more idiomatic...
std::string adder() {
static int i;
char buf[32];
snprintf(buf, sizeof(buf), "MYSTRING%i", i++);
return buf;
}
Related
NOTE: This is not about using a string for choosing the execution path in a switch-case block.
A common pattern in C++ is to use a switch-case block for converting integer constants to strings. This looks like:
char const * to_string(codes code)
{
switch (code)
{
case codes::foo: return "foo";
case codes::bar: return "bar";
}
}
However, we are in C++, so using std::string is more appropriate:
std::string to_string(codes code)
{
switch (code)
{
case codes::foo: return "foo";
case codes::bar: return "bar";
}
}
This however copies the string literal. Perhaps a better approach would be instead:
std::string const & to_string(codes code)
{
switch (code)
{
case codes::foo: { static std::string str = "foo"; return str; }
case codes::bar: { static std::string str = "bar"; return str; }
}
}
But this is kinda ugly, and involves more boilerplate.
What is considered the cleanest and most efficient solution for this problem using C++14?
This however copies the string literal.
Yes and no. It will copy the string literal indeed, but don't necessarily allocate memory. Check your implementation SSO limit.
You could use std::string_view:
constexpr std::string_view to_string(codes code) {
switch (code) {
case codes::foo: return "foo";
case codes::bar: return "bar";
}
}
You can find many backported versions like this one
However, sometimes a char const* is the right abstraction. For example, if you were to forward that string into an API that require a null terminated string, you'd be better off returning it a c style string.
But this is kinda ugly, and involves more boilerplate.
What is considered the cleanest and most efficient solution for this problem using C++14?
To answer the above, as #SamerTufail pointed out (and as I do it myself at work also), I would use enums and std::map like this.
typedef enum {
foo = 1,
bar = 2,
} Key;
std::map<Key, std::string> hash_map = { {Key::foo ,"foo"}, { Key::bar,"bar"} };
And then in main() you could get the value like this,
std::cout << hash_map.find(Key::foo)->second;
I would create a function for returning the second, where you would check the iterator for end(), otherwise the interator would be invalid and using it would be UB.
EDIT: As others have pointed out in the comments and as per this question, you could replace std::map, with std::unordered_map provided you do not need to keep elements in order.
And as per my experience, I always create such maps as static const. Therefore create them one time and use them many times to amortize the cost of creation.
Assuming that you eventually want a std::string with the label in it, the question is whether to create them:
1: in to_string()
2: in its caller
Using Compiler Explorer it's pretty easy to find out.
Turns out (with recent compilers) that there's not a lot difference between the two. Returning const char * has a slight edge on std::string
1:
#include <string>
char const * to_string(int code)
{
switch (code)
{
case 0: return "foo";
case 1: return "bar";
}
}
std::string foo(int x)
{
std::string s{to_string(x)};
return s;
}
2:
#include <string>
std::string to_string2(int code)
{
switch (code)
{
case 0: return "foo";
case 1: return "bar";
}
}
std::string foo2(int x)
{
std::string s{to_string2(x)};
return s;
}
Note:
I needed to add foo() in order to stop the compiler optimising even more heavily....
In both cases, the strings are short and can use the short-string optimisation. Both clang and GCC have managed a heap-elision. This is seriously impressive - the compiler knows that to_string() never returns a string bigger than 4 bytes long and then eliminates the code that would dynamically allocate heap memory.
The conclusion seems to be that writing natural, and tidy code has little performance penalty.
I am trying to make a get method in a class medicine to get the description.
As I know of that in C++, there is no data type "String" like in Java, therefore I need to make an array of char to save the description. I couldn't find a way to make a method with return type "array of chars", I use a pointer like the following.
class Medicine {
public:
char description[100] = "testing";
char *getDescription() {
char *p_description;
char *p_subDescription = (char*)malloc(100 * sizeof(char));
strcpy(p_subDescription, description);
p_description = p_subDescription;
free(p_subDescription);
return p_description;
}
};
I have a question: is there any other way I can do to make the code shorter? I feel like this is too much work just for a method to get a string.
Thank,
If you want this to be static (class-specific), the easiest way I can think of is a static, public property:
class Medicine {
public:
static const std::string description;
};
const std::string Medicine::description = "testing";
You have to decided on your flavour of C++. If you want "C with classes", C++ very close to C, then you should be passing strings about as char *s to memory allocated with malloc. Your code is nearly correct (however you free memory then return it), but most people write a little function called strdup (in fact it's often provided, which means ironically it's best to call it mystrdup() to avoid collisions)
char *mystrdup(char *str)
{
char *answer = malloc(strlen(st) +1);
if(answer)
strcpy(answer, str);
return answer;
}
If you are writing a more modern version of C++, use the std::string class. It isn't especially efficient and it's widely criticised for being over-desinged, but it's standard. It does memory management for you, and it's easy to create one.
You can use std::string like this
class Medicine {
public:
char description[100] = "testing";
std::string getDescription() {
return description;
}
};
It might not be advisable according to what I have read at a couple of places (and that's probably the reason std::string doesn't do it already), but in a controlled environment and with careful usage, I think it might be ok to write a string class which can be implicitly converted to a proper writable char buffer when needed by third party library methods (which take only char* as an argument), and still behave like a modern string having methods like Find(), Split(), SubString() etc. While I can try to implement the usual other string manipulation methods later, I first wanted to ask about the efficient and safe way to do this main task. Currently, we have to allocate a char array of roughly the maximum size of the char* output that is expected from the third party method, pass it there, then convert the return char* to a std::string to be able to use the convenient methods it allows, then again pass its (const char*) result to another method using string.c_str(). This is both lengthy and makes the code look a little messy.
Here is my very initial implementation so far:
MyString.h
#pragma once
#include<string>
using namespace std;
class MyString
{
private:
bool mBufferInitialized;
size_t mAllocSize;
string mString;
char *mBuffer;
public:
MyString(size_t size);
MyString(const char* cstr);
MyString();
~MyString();
operator char*() { return GetBuffer(); }
operator const char*() { return GetAsConstChar(); }
const char* GetAsConstChar() { InvalidateBuffer(); return mString.c_str(); }
private:
char* GetBuffer();
void InvalidateBuffer();
};
MyString.cpp
#include "MyString.h"
MyString::MyString(size_t size)
:mAllocSize(size)
,mBufferInitialized(false)
,mBuffer(nullptr)
{
mString.reserve(size);
}
MyString::MyString(const char * cstr)
:MyString()
{
mString.assign(cstr);
}
MyString::MyString()
:MyString((size_t)1024)
{
}
MyString::~MyString()
{
if (mBufferInitialized)
delete[] mBuffer;
}
char * MyString::GetBuffer()
{
if (!mBufferInitialized)
{
mBuffer = new char[mAllocSize]{ '\0' };
mBufferInitialized = true;
}
if (mString.length() > 0)
memcpy(mBuffer, mString.c_str(), mString.length());
return mBuffer;
}
void MyString::InvalidateBuffer()
{
if (mBufferInitialized && mBuffer && strlen(mBuffer) > 0)
{
mString.assign(mBuffer);
mBuffer[0] = '\0';
}
}
Sample usage (main.cpp)
#include "MyString.h"
#include <iostream>
void testSetChars(char * name)
{
if (!name)
return;
//This length is not known to us, but the maximum
//return length is known for each function.
char str[] = "random random name";
strcpy_s(name, strlen(str) + 1, str);
}
int main(int, char*)
{
MyString cs("test initializer");
cout << cs.GetAsConstChar() << '\n';
testSetChars(cs);
cout << cs.GetAsConstChar() << '\n';
getchar();
return 0;
}
Now, I plan to call the InvalidateBuffer() in almost all the methods before doing anything else. Now some of my questions are :
Is there a better way to do it in terms of memory/performance and/or safety, especially in C++ 11 (apart from the usual move constructor/assignment operators which I plan to add to it soon)?
I had initially implemented the 'buffer' using a std::vector of chars, which was easier to implement and more C++ like, but was concerned about performance. So the GetBuffer() method would just return the beginning pointer of the resized vector of . Do you think there are any major pros/cons of using a vector instead of char* here?
I plan to add wide char support to it later. Do you think a union of two structs : {char,string} and {wchar_t, wstring} would be the way to go for that purpose (it will be only one of these two at a time)?
Is it too much overkill rather than just doing the usual way of passing char array pointer, converting to a std::string and doing our work with it. The third party function calls expecting char* arguments are used heavily in the code and I plan to completely replace both char* and std::string with this new string if it works.
Thank you for your patience and help!
If I understood you correctly, you want this to work:
mystring foo;
c_function(foo);
// use the filled foo
with a c_function like ...
void c_function(char * dest) {
strcpy(dest, "FOOOOO");
}
Instead, I propose this (ideone example):
template<std::size_t max>
struct string_filler {
char data[max+1];
std::string & destination;
string_filler(std::string & d) : destination(d) {
data[0] = '\0'; // paranoia
}
~string_filler() {
destination = data;
}
operator char *() {
return data;
}
};
and using it like:
std::string foo;
c_function(string_filler<80>{foo});
This way you provide a "normal" buffer to the C function with a maximum that you specify (which you should know either way ... otherwise calling the function would be unsafe). On destruction of the temporary (which, according to the standard, must happen after that expression with the function call) the string is copied (using std::string assignment operator) into a buffer managed by the std::string.
Addressing your questions:
Do you think there are any major pros/cons of using a vector instead of char* here?
Yes: Using a vector frees your from manual memory management. This is a huge pro.
I plan to add wide char support to it later. Do you think a union of two structs : {char,string} and {wchar_t, wstring} would be the way to go for that purpose (it will be only one of these two at a time)?
A union is a bad idea. How do you know which member is currently active? You need a flag outside of the union. Do you really want every string to carry that around? Instead look what the standard library is doing: It's using templates to provide this abstraction.
Is it too much overkill [..]
Writing a string class? Yes, way too much.
What you want to do already exists. For example with this plain old C function:
/**
* Write n characters into buffer.
* n cann't be more than size
* Return number of written characters
*/
ssize_t fillString(char * buffer, ssize_t size);
Since C++11:
std::string str;
// Resize string to be sure to have memory
str.resize(80);
auto newSize = fillSrting(&str[0], str.size());
str.resize(newSize);
or without first resizing:
std::string str;
if (!str.empty()) // To avoid UB
{
auto newSize = fillSrting(&str[0], str.size());
str.resize(newSize);
}
But before C++11, std::string isn't guaranteed to be stored in a single chunk of contiguous memory. So you have to pass through a std::vector<char> before;
std::vector<char> v;
// Resize string to be sure to have memor
v.resize(80);
ssize_t newSize = fillSrting(&v[0], v.size());
std::string str(v.begin(), v.begin() + newSize);
You can use it easily with something like Daniel's proposition
I am trying to make a map which stores a string as an identifier and a function that returns a string i have tried typedef but i kept running into problems because i couldn't convert my typedef string (command)() to a regular string i have also tried map commands but it gives me an expression expected error but it does work if i replace string with int. Does anybody know a way of doing this? This is what my code looks like
#include "iostream"
#include <map>
#include <functional>
using namespace std;
class GameController {
public:
void inputReader();
private:
bool gameOver = false;
map<string,string(*)()> commands;//Does not work
//commands
string commandReader(string* inputCommand);
void initCommands();
//both
char* end();
string run();
//while attacking
string attack();
string usePotion();
string useItem();
//while in room
string engage();
string searchRoom();
string rest();
string checkBag();
string checkMap();
string checkStats();
//string save();
};
#endif //ROGUE_GAMECONTROLLER_H
#include "GameController.h"
GameController::GameController(){
initCommands();
}
void GameController::inputReader() {
while (!gameOver){
string x;
getline(cin,x);
cout << commandReader(&x) << endl;
}
}
string GameController::commandReader(string *inputCommand) {
for (map<string,string>::iterator it = commands.begin(); it!=commands.end(); ++it)
{
if(it->first == *inputCommand)
{
return it->second;
}
}
return "Computer says no type help for commands";
}
void GameController::initCommands() {
commands["end"] = end;
//while attacking
commands["run"] = run;
commands["attack"] = attack;
commands["use potion"] = usePotion;
commands["use item"] = useItem;
//while in room
commands["engage"] = engage;//TODO
commands["search"] = searchRoom;
commands["rest"] = rest;
commands["check bag"] = checkBag;
commands["map"] = checkMap;
commands["stats"] = checkStats;
}
This question is tagged C++11, so here's a concise example which uses unordered_map (a real hash map, unlike std::map which my STL reference says is commonly implemented using binary search trees), and std::function.
#include <iostream>
#include <functional>
#include <string>
#include <unordered_map>
std::string foo()
{
return "foo!";
}
struct MyClass
{
static std::string bar()
{ return "bar!"; }
std::string FizzBuzz() const
{ return "FizzBuzz!"; }
std::string operator()() const
{ return "Myclass!"; }
};
int main(int argc, char **argv)
{
MyClass mc;
std::unordered_map<std::string, std::function<std::string()>> commands;
commands["myfoo"] = foo;
commands["mybar"] = MyClass::bar;
commands["myfb"] = std::bind(&MyClass::FizzBuzz, mc);
commands["myclass"] = mc;
for( const auto &f : commands)
std::cout << f.second() << std::endl;
std::cout << commands["myfoo"]() << std::endl;
return 0;
}
Pointers to member functions is not like pointers to free functions or even static methods. For one thing all member functions have a hidden this pointer in the function parameters that makes all of this object magic work.
Going through step by step:
First, define a helper:
typedef string (GameController::*funcp)();
This defines type funcp which represents a pointer to a member function of GameController (to partly take care of the this problem) that takes no parameters and returns string
Then, modify your map to use funcp
map<string, funcp> commands;
Then you have to change the assignment of the member functions a bit to be brutally explicit that it is a pointer and a member of GameController
commands["end"] = &GameController::end;
You can also save yourself some runtime trouble and use an initializer list here rather than a function and a map in every single GameController object. That'll take a bit of extra explaining and I have to be on the move in a few minutes. Sorry about that. A static map with static initializing really is better and worth your time researching, though.
The next bit I stole from the C++ Super FAQ. Read this link. Worth reading all of it, because it heads off a lot of the question you will have.
#define CALL_MEMBER_FN(object,ptrToMember) ((object).*(ptrToMember))
This makes calling the function awesomely easy.
return CALL_MEMBER_FN(*this, it->second)();
And that should about do it for you.
edit:
Tweej demonstrates the generally better way to do this, std::function and std::bind, in their answer. Since I'm advocating the ancient ways, I'd like to explain why.
Two reasons: one is tunnel vision directly answering OP's question.
The second is With the ancient ways I could easily make commands static and save having to create a new copy of commands for every instance of GameController. When using std::bind, you have to have the bound object, and that ruins the static idea.
Poking around at the idea of just using std::function seems to have born fruit and rendered obsolete the ancient ways. gone is the CALL_MEMBER_FN macro. Gone is the funcp typedef
The map is now defined as static, what I was aiming for the the old-pre C++11 approach. Note the funcp typedef is replaced by a function that takes a pointer to GameController to supply this.
static map<string, std::function<string(GameController*)>> commands;
And the map is now rigged to use a static initializer list. No function required. This initializer needs to sit outside the class definition because... I'm not sure why. I think this is changed in C++14.
map<string, std::function<string(GameController*)>> GameController::commands
{
{"end", &GameController::end},
{"run", &GameController::run},
{"attack", &GameController::attack},
{"use potion", &GameController::usePotion},
{"use item", &GameController::useItem},
{"engage", &GameController::engage},
{"search", &GameController::searchRoom},
{"rest", &GameController::rest},
{"check bag", &GameController::checkBag},
{"map", &GameController::checkMap},
{"stats", &GameController::checkStats}
};
The map is initialized once and only once. All GameControllers will use the same commands, so the constructor is really dumb
GameController::GameController()
{
// init function is gone
}
Command reader gets a big rip-up, mostly because the point of a map is you can search it by the key. So I search for the key rather than iterating. The function call is now obvious and dead simple:
string GameController::commandReader(const string &inputCommand)
{
map<string, std::function<string(GameController*)>>::iterator found = commands.find(inputCommand);
if (found != commands.end())
{
return found->second(this);
}
return "Computer says no type help for commands";
}
Is it possible (albeit probably not good practice) to immediately set values of a struct from a function?
for example :
typedef struct
{
bool success;
std::string returnString;
} functionReturn;
functionReturn go(std::string word[])
{
functionReturn returnStruct;
...
return returnStruct;
}
int main()
{
std::string word[4];
... //assign values to word
std::string returnedString = go(word).returnString //will this work?
}
Is that possible or do I actually have to assign it to another functionReturn and pull out the string value from it?
Yes, that's perfectly possible; it's not different from calling a member function of a returned object, which is quite normal:
std::ostringstream s;
s << "file" << i;
std::ifstream f(s.str().c_str()); //notice calls here
Please don't use the typedef struct {...} name; idiom in C++. This is a holdover from C and has no value in C++. Just use the standard technique: struct name {...};
There is nothing technically wrong with doing what you're doing. Just be careful you don't return a reference to a local, or anything like that. You're not here.
In fact, you could have a method that does something with the parameters and returns a reference to the object, and then chain together method calls, like this:
struct functionReturn
{
functionReturn& doSomething() { return * this; }
functionReturn& doSomethingElse() { return * this; }
};
int main()
{
functionReturn fr;
fr.doSomething().doSomethingElse();
}
This is also valid. It's called method chaining. The question is not weather it's valid, but if it's semantically clear and maintainable. Some people consider constructs like this to be elegant and concise. Others consider it to be an abomination. Count me in the latter group. Decide for yourself.