C++ int to string, concatenate strings [duplicate] - c++

This question already has answers here:
How to concatenate a std::string and an int
(25 answers)
Closed 8 years ago.
I'm new to C++ and working on a simple project. Basically where I'm encountering a problem is creating a file with a number (int) in the file name. As I see it,I have to first convert the int to a string (or char array) and then concatenate this new string with the rest of the file name.
Here is my code so far that fails to compile:
int n; //int to include in filename
char buffer [33];
itoa(n, buffer, 10);
string nStr = string(buffer);
ofstream resultsFile;
resultsFile.open(string("File - ") + nStr + string(".txt"));
This gives a couple compilation errors (compiling in Linux):
itoa not declared in this scope
no matching function for call to ‘std::basic_ofstream char, std::char_traits char ::open(std::basic_string char, std::char_traits char , std::allocator char )’
I've tried the advice here: c string and int concatenation
and here: Easiest way to convert int to string in C++ with no luck.
If I using the to_string method, I end up with the error "to_string not a member of std".

You could use a stringstream to construct the filename.
std::ostringstream filename;
filename << "File - " << n << ".txt";
resultsFile.open(filename.str().c_str());

For itoa, you are likely missing #include <stdlib.h>. Note that itoa is non-standard: the standard ways to format an integer as string as sprintf and std::ostringstream.
ofstream.open() takes a const char*, not std::string. Use .c_str() method to obtain the former from the latter.
Putting it together, you are looking for something like this:
ostringstream nameStream;
nameStream << "File - " << n << ".txt";
ofstream resultsFile(nameStream.str().c_str());

You want to use boost::lexical_cast. You also need to include any needed headers:
#include <boost/lexical_cast>
#include <string>
std::string nStr = boost::lexical_cast<std::string>(n);
then it's simply:
std::string file_name = "File-" + nStr + ".txt";
because std::strng plays nicely with string literals (e.g. ".txt").

Using std::ostringstream:
std::ostringstream os;
os << "File - " << nStr << ".txt";
std::ofstream resultsFile(os.str().c_str());
Using std::to_string (C++11):
std::string filename = "File - " + std::to_string(nStr) + ".txt";
std::ofstream resultsFile(filename.c_str());

for itoa function
include <stdlib.h>
consider this link
http://www.cplusplus.com/reference/cstdlib/itoa/

You can use std::stringstream
std::stringstream ss;
ss << "File - " << n << ".txt";
Since the constructor requires a char pointer, you need to convert it into a char pointer using
ofstream resultsFile(ss.str().c_str());

Related

C++ arguments to integer

I am attempting to create a text file with the args[1] which should be an integer. The file name should be ex "3.txt", but the file i am getting is called just "t". The number argument is correct, but the file name is somehow getting incorrect. What suggestions do you have to improve this code both readability and usability?
int main(int argc,char *args[])
{
ofstream myFile;
int num = atoi(args[1]);
myFile.open(num + ".txt");
if (myFile.is_open())
{
myFile << "num\n" ;
for(int i=num; i > 0; i--)
myFile << i + ",";
myFile.close();
}
}
Tricky one. When you do :
myFile.open(num + ".txt");
...you're not actually translating the int as a string. Instead, you're taking the char const* that is ".txt" and offseting it by num (3 in your case) chars before passing it to open, hence your "t" file.
I see you're using C++. Save yourself some headaches by using std::string, and C++11's std::to_string functions if you can.
I can't see a reason why you are converting the command line argument to a number in 1st place here.
Change your code like
myFile.open((std::string(argv[1]) + ".txt").c_str());
or for more recent compiler versions (capable of c++11 standards)
myFile.open(std::string(argv[1]) + ".txt");
You don't need to have argv[1] converted to be to a numeric value.
Your problems are resulting from use of wrong types. First of all int() + "text" are defined, but does not do what you expect. It's not operation on strings, but on pointers. You had better use a language. c++ contains std::string and it will be easy wit him. Initially you should make string from args[1]:
string num(args[1]);
Of course, it should be given and you need to check it fitst!
if(argc < 2)
//some throw
After it, operator plus will work in accordance with your wishes. So, you just add ".txt" to num.
num += ".txt"
Now you have to open file with ofstrem. It expect const char*, and string on given address should ended with '\0' so you can use std::basic_string::c_str.
ofstream my_file(num.c_str());
Well to know, since c++11 you can give just std::string:
ofstream my_file(num);
Let's get to the main ("C++ arguments to integer") topic. You can just use std::stoi. As you can see, you don't need to worry about chars after number.
for(int i=stoi(num); i > 0; i--)
myFile << i << ","; //it can't be i + "," - as above
Or if you want to convert directly argument to integer, you have the ability to use std::atoi.
int i = atoi(args[1]);
Finally begin of your code should looks like this:
if(argc < 2)
{//some throw}
ofstream myFile;
string num =string(args[1])+".txt";
myFile.open(num.c_str());

Converting int to string [duplicate]

This question already has answers here:
Easiest way to convert int to string in C++
(30 answers)
Closed 8 years ago.
Here str2 is a string I need to append and str1 is the string I append onto str2. After I append last to str2 I need to append a number (int cnt) to str2. So I am using the below code, which came to my mind and it is working. Is it wrong to code like this, since I saw the usage of string s = lexical_cast<string>(a); and itoa (i,buffer,10); implementations where compiler complaints about the library.
string str2;
string str1;
int cnt;
str2 += str1 ;
str2 += char(cnt+48);//cnt converted to ASCII char and appended;
This statement
str2 += char(cnt+48);
is bad. Firstly it uses magic number 48. It would be better to write at least as
str2 += char( cnt + '0' );
Secondly the code will work only if cnt contains a number with one digit.
It would be better to use standard function std::to_string For example
str2 += std::to_string( cnt );
If you don't want to use c++11 and its std::to_string(...) you can use ostringstream class.
#include <iostream>
#include <sstream>
using namespace std;
int main()
{
ostringstream ss;
ss << 1;
string str = ss.str();
cout << str << endl;
return 0;
}
Output:
1

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
}

Convert from unsigned short to string c++ [duplicate]

This question already has answers here:
Append an int to a std::string [duplicate]
(4 answers)
Closed 10 years ago.
How can I convert from unsigned short to string using C++?
I have tow unsigned short variables:
unsigned short major = 8, minor = 1;
I want to join them for on string, looks like:
std::string version = major + "." + minor;
how can I do it? will aprrechiate a small sample code.
Thanks
could use std::stringstream or std::to_string(C++11) or boost::lexical_cast
#include<sstream>
std::stringstream ss;
ss << major << "." << minor;
std::string s = ss.str();
std::to_string:
std::string s = std::to_string(major) + "." +std::to_string(minor);
In C++11, you don't need some stream do do this:
std::string version = std::to_string(major)
+ "." + std::to_string(minor);
std::ostringstream oss;
oss << major << "." << minor;
Receive the generated string via oss.str().
Use std::ostringstream. You need to include the header <sstream>.
std::ostringstream ss;
ss << major << "." << minor;
std::cout << ss.str();

String concatenation in C++ problem

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/