Deleting a file with name created using a string variable - c++

I am writing a function which will give users an opportunity to change their username. To do this I was trying to rename the file in which their data is stored. I have come up with a way of doing this, which doesn't quite work but I think I am close.
The filename is originally created like this -
std::cout << "Please enter a username: ";
std::getline (std::cin, username);
std::ofstream fout (username + ".txt");
which works fine. And then if they later choose to change their username
std::cout << "Please type in your new username." << std::endl;
std::getline (std::cin, newUsername);
std::ofstream fout (newUsername + ".txt");
// I copied the contents of username.txt to newUsername.txt here
which again works fine.
The problem lies below.
the problem lies in deleting the original file, more specifically when adding the file extension .txt
I have included #include for the remove() functionality
And added .c_str() to username as I believe remover () will only take a C string (char*), not a C++ string.
remove(username.c_str() + ".txt"); // error expression must have integral or enum type referring to ".txt".
Thanks in advance for everyones time

Simple enough
remove((username + ".txt").c_str());
The return value from username + ".txt" is called a temporary (because it is an unnamed value) but there is nothing that says you can't call a method (like c_str) on a temporary object.

remove takes a const char* as an argument, and you cannot add two const char*s together using the + operator. Therefore, the solution is to add them as strings then call c_str() on the result.
remove((username + std::string(".txt")).c_str());

Your problem lies here:
remove(username.c_str() + ".txt"); // error expression must have integral or enum type referring to ".txt".
Adding two char*s doesn't produce a string.
This may be a better approach:
auto filename = username + ".txt"
remove(filename.c_str())

Your problem lies here:
remove(username.c_str() + ".txt"); // error expression must have integral or enum type referring to ".txt".
Adding two const char*s doesn't produce a (std::)string.
This may be a better approach:
auto filename = username + ".txt"
remove(filename.c_str())
Note that this produces a relative filename whereas an absolute filename may be preferable depending on how this is called.

Related

String as function and called by other sub class with integer value

I want to create a file with C++ and write something in it. I have two classes, one with a Vererbung::writer(string name) and another subclass called Vererbung1(int zahl). Without the integer it works peferctly but when I want to write the integer to string and paste it after the function it wont work.
this works normally
Vererbung.cpp
void Vererbung::Writer(string name)
{
ofstream text;
text.open ("test.txt", ios::trunc);
text <<"write something\n";
text <<"again2 \n";
text <<"again 3\n";
text << name;
text.close();
}
Vererbung1.cpp
include "Vererbung.h"
void Vererbung1::Writer(int zahl)
{
std::ostringstream ostr;
ostr<< zahl;
name = "\n" "Test\n""Test\n""Test\n" ostr.str();
Vererbung::Writer(name);
}
When I run it in main it says that I need a ';' before ostr.str(); how can I fix this, If I want a integer value to string in a file in it?
This problem is very unclearly stated but, if we assume that name is an std::string, then:
name = "\n" "Test\n""Test\n""Test\n" ostr.str();
This is just a bunch of string literals written next to each other, followed by an std::string expression also just randomly floating there in free space.
Your computer doesn't know what you want it to do.
Although you actually can concatenate string literals in this way (literals are something like "hello world", but not something like aStringVariable), that doesn't apply to arbitrary expressions (and you don't even need it where you've used it).
I think that what you meant was this:
name = "\nTest\nTest\nTest\n" + ostr.str();
I hope that your C++ book teaches this; if not, get a better one.

How can I assign boost::filesystem::directory_entry::path() value to a string?

I'm trying to write an algorithm that iterates recursively through a directory and compares each folder, sub-folder and file name to a user-defined regex object.
I've found this piece of code for the iteration part:
path p(FilePath);
for (directory_entry& x : recursive_directory_iterator(p))
std::cout << x.path() << '\n';
Where Filepath is the directory path defined by the user at runtime.
It works great to print out paths on the console, but I can't figure out a way to use path() to do what I want, which would be to assign its value to a string and then compare that string to my regex object.
I've been looking at other member function in boost::filesystem::directory_entry but I'm not really having any luck so far.
Could anyone point me in the right direction?
Thanks.
EDIT:
I'm dumb.
It works great to print out paths on the console, but I can't figure
out a way to use path() to do what I want, which would be to assign
its value to a string and then compare that string to my regex object.
boost::path has got a string member that either performs a conversion to a string type, or returns a const reference to the underlying storage mechanism (typically std::string) (see boost path documentation). Therefore, just call:
x.path().string()
Also, you might want to add some braces behind your for loop:
path p(FilePath);
std::string temppath;
for (directory_entry& x : recursive_directory_iterator(p))
{
temppath = x.path().string();
std::cout << temppath << std::endl;
}
The way you structured the code, std::cout would not be called as part of the loop, but only after the loop completed in its entirety... classic bug!!!

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

Standard Stream Printing Unrelated Characters

I was coding something and my code didn't work correctly in some situations, so I decided to write some output to file for debugging. The program just concatenates some characters from a string (and it didn't get out of bounds) and printed them to the file. It has no thing as error reporting or something, and the input string is just a bunch of random characters. But, i get some junk in the output, such as:
f::xsgetn error reading the file
sgetn error reading the file
ilebuf::xsgetn error reading the file
(I removed program's output and this is just the extra stuff.)
As far as I know, if there are any errors, an exception must be thrown. What happens and how can I fix it?
The same thing happens when I print the output using standard output. All used libraries are standard libraries (eg. iostream, fstream, etc.)
PS: For some reasons, I can't publish all the code. Here is the part that creates the output and passes it to stream: (tri is and string, and is defined previously. Center is an integer and is inside the bounds of the string. fout is a previously defined file stream.)
string op = "" + tri[center];
fout << center << "<>" << op << endl;
Since tri is a string, tri[center] is a char.
The type of "" is const char[], which can't be added to a char.
Instead it is implicitly converted to const char*, which can be added to a char.
Unfortunately for you, the result of that is that the integer value of tri[center]is added to that pointer as an offset, not as a string concatenation, and the particular area of memory that the result refers to doesn't contain what you're looking for but instead contains other static strings like e.g. "error reading the file".
To fix it, use
string op = string("") + tri[center];
instead.
I encountered the same problem in another program, where I had written:
str += blablabla + "#";
and I saw some unrelated characters being printed. I fixed it this way:
str = str + blablabla + "#";
and it worked!
There is some problem with the += operator for string.