String concatenation in C++ problem - c++

everybody I have problem with string concatenation in C++, here is my code
map<double, string> fracs;
for(int d=1; d<=N; d++)
for(int n=0; n<=d; n++)
if(gcd(n, d)==1){
string s = n+"/"+d;// this does not work in C++ but works in Java
fracs.insert(make_pair((double)(n/d), s));
}
How can I fix my code?

Try like this.
stringstream os;
os << n << "/" << d;
string s =os.str();

In C++ you have to convert an int to a string before you can concatenate it with another string using the + operator.
See Easiest way to convert int to string in C++.

Use streams, in your case, a stringstream:
#include <sstream>
...
std::stringstream ss;
ss << n << '/' << d;
Later, when done with your work, you can store it as an ordinary string:
const std::string s = ss.str();
Important (side-) note: Never do
const char *s = ss.str().c_str();
stringstream::str() produces a temporary std::string, and according to the standard, temporaries live until the end of the expression. Then, std::string::c_str() gives you a pointer to a null-terminated string, but according to The Holy Law, that C-style-string becomes invalid once the std::string (from which you receved it) changes.
It might work this time, and next time, and even on QA, but explodes right in the face of your most valuable customer.
The std::string must survive until the battle is over:
const std::string s = ss.str(); // must exist as long as sz is being used
const char *sz = s.c_str();

n and d are integers. Here is how you can convert integer to string:
std::string s;
std::stringstream out;
out << n << "/" << d;
s = out.str();

You could use a stringstream.
stringstream s;
s << n << "/" << d;
fracs.insert(make_pair((double)n/d, s.str()));

No one has suggested it yet but you can also take a look at boost::lexical_cast<>.
While this method is sometimes criticized because of performance issues, it might be ok in your situation, and it surely makes the code more readable.

Unlike in Java, in C++ there is no operator+ that explicitly converts a number to a string. What is usually done in C++ in cases like this is...
#include <sstream>
stringstream ss;
ss << n << '/' << d; // Just like you'd do with cout
string s = ss.str(); // Convert the stringstream to a string

I think sprintf(), which is a function used to send formatted data to strings, would be a much clearer way to do it. Just the way you would use printf, but with the c-style string type char* as a first(additional) argument:
char* temp;
sprint(temp, "%d/%d", n, d);
std::string g(temp);
You could check it out at http://www.cplusplus.com/reference/cstdio/sprintf/

Related

Converting int to string and adding to an existin string in c++

I was wondering how I could convert an int to a string and then add it to an existin string. i.e.
std::string s = "Hello";
//convert 1 to string here
//add the string 1 to s
I hope I'm making sense. Thank you very much in advance for any answer.
If the number you want to append is an integer or floating point variable, then use std::to_string and simply "add" it:
int some_number = 123;
std::string some_string = "foo";
some_string += std::to_string(some_number);
std::cout << some_string << '\n';
Should output
foo123
The "modern" way is to use std::to_string(1). In fact, various overloads of std::to_string exist for different number types.
Putting this together you can write std::string s = "Hello" + std::to_string(1);
Alternatively you can use std::stringstream which can be faster due to fewer string concatenation operations which can be expensive:
std::stringstream s;
s << "Hello" << 1;
// s.str() extracts the string

Different values on the function implementation

I'm kind of new with programming and I have wired problem.
I tried to search and read about it, but without success.
I have main file and one class (on windows)
main:
main()
{
LogOut x();
x.WriteToDelayFile(1.2, 3);
}
LogOut class:
void LogOut::WriteToDelayFile(double simTime, int nodeNum)
{
string fileName = "Delay" + nodeNum;
FILE* pFile = OpenFile(fileName);
fputs ("something\n",pFile);
}
I can't figure it out but when I call to WriteToDelayFile(2, 3) with values, I get garbage values edit: (for example, on debug- nodeNum=321546 instead of nodeNum=3) on the LogOut::WriteToDelayFile(double simTime, int nodeNum) implementation
Why does it happen?
Thanks.
As user657267 pointed out in his comment, you may not concatenate a string literal and an int string fileName = "Delay" + nodeNum;. Here you are getting a pointer into the literal, that may even be out of range:
string s = "hello"+1; // leads to "ello" in s
The probably intended concatenation can be done using a stringstream:
#include <sstream>
#include <assert>
void concat_check()
{
std::stringstream ss;
ss << "hello" << 1;
assert(ss.str() == "hello1");
}
Wolf you are a little bit wrong
string s = "hello"+3;
gives "lo" in s data
and
string si = string("hello")+3;
is incorrect you need to use stringstream instead
std::stringstream ss;
ss << "hello" << 3;
std::string s = ss.str();
Dudi Reuveni how can you tell that nodeNum has wrong data?

Best way to cast numbers into strings in C++? [duplicate]

This question already has answers here:
Easiest way to convert int to string in C++
(30 answers)
Closed 9 years ago.
Coming from a C# background, In C# I could write this:
int int1 = 0;
double double1 = 0;
float float1 = 0;
string str = "words" + int1 + double1 + float1;
..and the casting to strings is implicit. In C++ I understand the casting has to be explicit, and I was wondering how the problem was usually tackled by a C++ programmer?
There's plenty of info on the net already I know, but there seems to quite a number of ways to do it and I was wondering if there wasn't a standard practice in place?
If you were to write that above code in C++, how would you do it?
Strings in C++ are just containers of bytes, really, so we must rely on additional functionality to do this for us.
In the olden days of C++03, we'd typically use I/O streams' built-in lexical conversion facility (via formatted input):
int int1 = 0;
double double1 = 0;
float float1 = 0;
std::stringstream ss;
ss << "words" << int1 << double1 << float1;
std::string str = ss.str();
You can use various I/O manipulators to fine-tune the result, much as you would in a sprintf format string (which is still valid, and still seen in some C++ code).
There are other ways, that convert each argument on its own then rely on concatenating all the resulting strings. boost::lexical_cast provides this, as does C++11's to_string:
int int1 = 0;
double double1 = 0;
float float1 = 0;
std::string str = "words"
+ std::to_string(int1)
+ std::to_string(double1)
+ std::to_string(float1);
This latter approach doesn't give you any control over how the data is represented, though (demo).
std::stringstream
std::to_string
If you can use Boost.LexicalCast (available for C++98 even), then it's pretty straightforward:
#include <boost/lexical_cast.hpp>
#include <iostream>
int main( int argc, char * argv[] )
{
int int1 = 0;
double double1 = 0;
float float1 = 0;
std::string str = "words"
+ boost::lexical_cast<std::string>(int1)
+ boost::lexical_cast<std::string>(double1)
+ boost::lexical_cast<std::string>(float1)
;
std::cout << str;
}
Live Example.
Note that as of C++11, you can also use std::to_string as mentioned by #LigthnessRacesinOrbit.
Being a C developer, I would use the C string functions, as they are perfectly valid in C++, and let you be VERY explicit with respect to the formatting of numbers (ie: integers, floating point, etc).
http://www.cplusplus.com/reference/cstdio/printf/
In the case of this, sprintf() or snprintf() is what you are looking for. The formats specifiers make it very obvious in the source code itself what your intent was as well.
The best way to cast numbers into std::string in C++ is to use what is already available.
The library sstream provide a stream implementation for std::string.
It is like using a stream ( cout, cin ) for example
Its easy to use :
http://www.cplusplus.com/reference/sstream/stringstream/?kw=stringstream
#include <sstream>
using std::stringstream;
#include <string>
using std::string;
#include <iostream>
using std::cout;
using std::endl;
int main(){
stringstream ss;
string str;
int i = 10;
ss << i;
ss >> str;
cout << str << endl;
}

Making a sequential list of files

I have been stuck on a problem for a while now and can't seem to find an answer.
I'm trying to create multiple files with the same name but a different number at the end each time, I have attempted this at first just by using
int seq_number = 1;
while (seq_number < 10)
{
ofstream fsave;
fsave.open("filename" + seq_number + ".txt");
fsave << "blablabla";
fsave.close();
seq_number = seq_number + 1;
}
But that gives me a very strange result where the letters get jumbled up, I'm not sure how that works but I know it doesn't.
I've looked online and found stringstream or sstream, and tried with that, but it keeps giving me errors too,
string filename;
filename = "character";
ostringstream s;
s << filename << seq_number;
filename(s.str());
fsave.open(filename + ".txt");
fsave << "blabla"
fsave.close(;)
but i keep getting an error:
no match for call to `(std::string) (std::basic_string, std::allocator >)'
I'm not sure how string stream works exactly so im working off of instinct, but i would appreciate any way this is possible, and honestly I think I would prefer doing it without sstream, but i need a way to get an int and str together and save a filename that is a string.
unless you know a better way ;) thanks guys
filename(s.str());
this is wrong; you are not constructing a new variable (filename is already constructed), what you want here is an assignment.
filename = s.str();
Then,
fsave.open((filename + ".txt").c_str());
(although, if you are using C++11, this change is not necessary)
Still, personally I would just construct the whole file name with the stream:
ostringstream s;
s<<"character"<<seq_number<<".txt";
fsave.open(s.str.c_str());
I'm not sure how string stream works exactly so im working off of instinct
This is a very bad idea, C++ is often quite a minefield of bizarre syntax, segfaults and undefined behavior, going by instinct usually leads to disaster.
About the errors you get:
fsave.open("filename" + seq_number + ".txt");
This shouldn't even compile, since you are summing an integer to a const char * (thus moving the "start of the string"), and then summing it again to a const char *, which is not allowed at all. Maybe it could compile if it were like this:
fsave.open("filename" + seq_number);
but it won't give the required result - "filename" is a pointer (not a C++ string), so summing an integer to it just moves the pointer of the given offset.
In your second snippet, instead, you are using an object (filename) as it were a function, which is only allowed if the class overloads operator(); thus, the compiler complains that such an operation is not allowed on that object.
Replace
fsave.open(filename + ".txt");
With
fsave.open( (filename + ".txt").c_str() );
This is because the ofstream constructor takes as parameter a char const *, not an std::string.
Also, your first version generates strange file names because in C and C++, adding an integer to a char * simply offsets within the character array. It does not append to the string.
In C++ you can not convert an int to a string, or concatenate it to one -- not to a ´char*`:
"filename" + seq_number + ".txt"
^const char* ^int ^const char*
Also, ostream can not recieve the filename as a string, it must be a const char*, which you can acquire temporarily via ´c_str()`.
Use sprintf, ostringstream (as you did), or C++11 to_string to do that:
#include <string>
#include <iostream>
int main() {
for(int seq_number = 1; i<10; ++i) {
std::string num_as_string = std::to_string(seq_number); // make a string, C++11
std::string filename = "abcd" + num_as_string + ".txt";
std::ostream f(filename.c_str());
f << "text\n";
}
}
This (modulo typos) should get you started.
You can do it like this:
ostringstream s;
s << "character" << seq_number << ".txt";
fsave.open(s.str());
fsave << "blabla";
fsave.close();
And this is how you could implement the original loop:
for (int seq_number = 1; seq_number<10; ++seq_number)
{
ostringstream s;
s << "filename" << seq_number << ".txt";
ofstream fsave(s.str());
fsave << "blablabla";
}
You could do something like this:
#include <iostream>
#include <string>
#include <sstream>
int main (int argc, char const* argv[])
{
std::string filename;
int seq_number = 10;
filename = "character";
std::stringstream s;
s << filename << seq_number << ".txt";
filename = s.str();
std::cout<< filename << std::endl; // <-- Here open your file instead print the filename
}

String as a parameter (C++)

Is this example code valid?
std::string x ="There are";
int butterflies = 5;
//the following function expects a string passed as a parameter
number(x + butterflies + "butterflies");
The main question here is whether I could just pass my integer as part of the string using the + operator. But if there are any other errors there please let me know :)
C++ doesn't do automatic conversion to strings like that. You need to create a stringstream or use something like boost lexical cast.
You can use stringstream for this purpose like that:
#include <iostream>
#include <sstream>
using namespace std;
int main()
{
stringstream st;
string str;
st << 1 << " " << 2 << " " << "And this is string" << endl;
str = st.str();
cout << str;
return 0;
}
A safe way to convert your integers to strings would be an excerpt as follows:
#include <string>
#include <sstream>
std::string intToString(int x)
{
std::string ret;
std::stringstream ss;
ss << x;
ss >> ret;
return ret;
}
Your current example will not work for reasons mentioned above.
No, it wouldn't work. C++ it no a typeless language. So it can't automatically cast integer to string. Use something like strtol, stringstream, etc.
More C than C++, but sprintf (which is like printf, but puts the result in a string) would be useful here.