Concatenate write parameters in C++ - c++

I need to concatenate the parameters in the write function. How would I do this?
Example: ofstream write(newFolder concat "/newfile.txt");
mkdir(newFolder);
ofstream write (wantTo "concat here");
write << "Sup mo fo";
write.close();

If newFolder is a std::string, you can simply use newFolder + "/newfile.txt". You'd have to make sure newFolder does not end with a / or a \ though. You may need to use the c_str() function on your std::string if you require a char* in your write function.

While using std::string is the preferred way, be careful because older versions of the standard library doesn't support an open method that takes a std::string as argument.
If you get an error in the call to open when using std::string, then you have to do it in two steps:
std::string newFolder = "/path/to/folder";
mkdir(newFolder.c_str(), 0644); // The 'mkdir' function wants 'const char *'
// Has to concatenate strings here if your standard library is too old
std::string folderAndFile = newFilder + "/filename";
std::ofstream output(folderAndfile.c_str());

Related

C++ syntax to name file via variable and text

I have a program that takes in the name of a file as an argument (example: books.txt), runs, and then outputs the results to a new text file. I need to name the output file with an addendum (example: books_output.txt).
The method that I tried was
ofstream outputFile;
outputFile.open(argv[1] + "_output.txt", ofstream::out);
but this didn't compile.
How can I make this work?
Your statement should look like this (as mentioned in my comment):
outputFile.open(std::string(argv[1]) + "_output.txt", ofstream::out);
// ^^^^^^^^^^^^ ^
assumed argv[1] comes from the standard main() signature
int main(int argc, char* argv[])
argv[1] is a char* pointer and you can't concatenate char* pointers that way.
As some people bother regarding support of obsolete C++ standard versions, the std::ofstream::open() signatures of earlier versions didn't support a const std::string parameter directly, but only const char*. In case you have that situation your statement should look like
outputFile.open((std::string(argv[1]) + "_output.txt").c_str(), ofstream::out);
you cannot put a + between 2 C strings. Use std::string instead. Do this
ofstream outputFile;
std::string fname = std::string(argv[1]) + "_output.txt";
outputFile.open(fname.c_str(), ofstream::out);
More recent c++ versions allow
outputFile.open(fname, ofstream::out);
which reads nicer but means the same thing

Use string or array of char for filename?

I have come across something online about strings. It says to use an array of chars for a filename input and not string. Why is that?
You seem to be using an older version of C++, where std::ifstream::open accepts only a const char *, not a std::string (see docs):
void open (const char* filename, ios_base::openmode mode = ios_base::in);
As you can see, you cannot pass a std::string here.
In C++11 and newer, you can pass a std::string as well:
void open (const string& filename, ios_base::openmode mode = ios_base::in);
A better approach: use std::string to input the file name and the do File.open(filename.c_str()); to open the file.
That advice is basically wrong. The problem it is attempting to get around is that back in the olden days, file streams took const char* as the argument for the file name, so you couldn't directly use a std::string for the name. Of course, the answer to that is to use std::string, and call c_str() to pass the file name:
std::string name = "test.txt";
std::ofstream out(name.c_str());
These days, file streams also have a constructor that takes std::string, so you can do this:
std::string name = "test.txt";
std::ofstream out(name);
I suspect it is because of the prototype of ifstream::open(const char*). Personally, I would have written the code as:
string filename;
cin >> filename;
ifstream testmarks;
testmarks.open(filename.c_str());
But that is yet more complexity to explain, and this is obviously aimed at someone very new to C++.
This is wrong, and it's a wonderful way to write programs vulnerable to buffer overflows, at least as written in the example.
The "open" function expect char pointer.
However it is fine to do this:
std::string filename;
std::cin >> filename;
std::ifsteam f;
f.open(filename.c_str());

how can i add this variable to my path for ifstream?

I'm trying to append my path and contain a variable as part of the path but I'm getting an error.
What's wrong with it?
fstream fin("E:\\Games\\maps\\" + this->MapNumber + ".map", ios::in|ios::binary|ios::ate);
this->MapNumber is a USHORT
error: 13 IntelliSense: expression must have integral or unscoped enum type
In C++ you can't use + to concatenate literal strings. You can use + with std::strings to concatenate them, but that won't work with integer or other types. You need to use a stream instead. Insertion and extraction into a stream will cause the types that support it to represent themselves as text, but you probably already knew this from general I/O.
Try with something like this:
std::stringstream filename;
filename << "E:\\Games\\maps\\" << this->MapNumber << ".map";
std::fstream fin(filename.str().c_str(), ios::in|ios::binary|ios::ate);
Just like with everything else, to use something you need to include the header that declares it first. In order to use std::stringstream you need to include <sstream>.
You can't use operator+ on a string and another type like string or so you can either:
Option1: turn all variables into strings to append them
string s = string("E:\\Games\\maps\\") + string(itoa(this->MapNumber)) + string(".map");
option2: use stringstream as #k-ballo explained
option3: use the good old C fprintf (my personal favourite)
char str[100];
fprintf(str, "E:\\Games\\maps\\ %d .map", this->MapNumber);

using an integer number as the outstream file name?

I'm trying to write an mpi program where each node knows its own rank, which is an integer.
I this program I hope each node to create a .txt file with its rank as the file name. That is, I hope the program to generate a file called rank.txt where rank is an integer.
I know how to convert an int to string, but I am quite confused about how I can combine that string with .txt and put it into a filename. What is the easiest way to do it?
Thanks in advance.
EDIT
I have combined the number with .txt and put them into a string filename but when I typed std::ofstream out_stream(filename) the compiler tells me that
no matching constructor for initialization `std::outstream`
How can I put the string into a filename?
The problem is that there's no constructor for std::ofstream that takes a std::string. You need to pass const char*, so just say:
std::ofstream out_stream(filename.c_str());
Things have changed with the latest standard revision, though, so check your compiler documentation for how to enable C++11.
If you've already converted the int to an std::string, say rank_s, then rank_s + ".txt" should be enough.
use fstream and the << operator.
For string concatenation:
std::stringstream vIndex;
vIndex << i;
std::string index = vIndex.str() + ".txt";
If you can use boost:
std::string filename = boost::lexical_cast<std::string>(rank) + ".txt";
Otherwise (for example):
std::ostringstream s;
s << rank;
std::string filename = s.str() + ".txt";
std::string filename = std::to_string(i) + ".txt";
Needs an up to date compiler that supports c++11 for this
edited to answer question :-
If you have c++11 just do
std::ofstream out_stream(std::to_string(i) + ".txt");
If you don't then you're best looking at the other answers

Pass path to file / filename as argument to a function that prints the file to screen in C++

As the title says, is there any way to pass the path to the file / filename to open as an argument in the function?
I've written a short code for printing a .txt-file to the screen in C++, but instead of having all the code in the main(), I'd rather have it as an own function that I can call with the filename of the file to open as the only input argument.
Basically the beginning of the function would look like
void printFileToScreen()
{
ifstream fin;
char c;
fin.open("FILE_TO_OPEN.txt", ios::in);
blablabla
}
Now is there any way to pass "FILE_TO_OPEN.txt" when I call the function?
I've tried
void printFileToScreen(string str)
{
ifstream fin;
char c;
fin.open(str, ios::in);
blablabla
}
where I call the function like printFileToScreen("FILENAME.txt"), but with no luck, so I'm not sure how to do this.
Hope anyone can help :)
Unfortunately, the iostream functions deal with const char* types rather than with std::string (the iostream functions were developed independently of the STL). You instead could use std::string::c_str() to obtain a const char*:
fin.open(str.c_str(), ios::in);
As a general design rule, I would not pass the file name to the called function. I would pass the already opened std::istream object to read from. This allows you to do the job of printing in a function, and to do the job of opening the file and dealing with non-existent files in another. This has the bonus of being able to pass std::cin to your function!
Try changing your function to look like this :
void printFileToScreen(const string &str);
//If you pass a const char*, a string will be constructed
or this :
void printFileToScreen(const char *);
The function you wrote expects an instance of std::string to be passed by value.
Never mind, after some more trying and failing I found out that I needed to pass a char pointer, and not a string. :)
Of course you can pass the filename as a function parameter. If in doubt, pass a "const char*" rather than a string. I should work.