Delete file with string variable

I am trying to delete a .txt file. When hardcoding the .txt, like Banana.txt it functions like expected with the remove function. But when i am trying to use a string variable to choose which file i should remove it says it cant recognise remove.

1
2
3
4
5
6
  void eraseUser() {
    std::string username;
    std::cout << "Which file do you want to erase? (Case sensitive)" << std::endl;
    std::cin >> username;
    std::remove(username + ".txt");
  } 
try: username+= ".txt" as a new statement and then pass in only username, not the addition.

Have a look at https://en.cppreference.com/w/cpp/io/c/remove

std::remove takes a const char*, not an std::string.

Your compiler should inform you about this with something like:
error: cannot convert 'std::__cxx11::basic_string<char>' to 'const char*' for argument '1' to 'int remove(const char*)'


Consider:
1
2
3
    std::cin >> username;
    username = username + ".txt";
    std::remove(username.c_str());


Kind regards, Nico
Last edited on
std::remove(username.c_str());

How do i understand the .c_str() ??

c_str() returns a non-modifiable standard C character array version of the string.
https://en.cppreference.com/w/cpp/string/basic_string/c_str
.c_str() returns a C style string, which is just an array of characters, which is how the C language (and C++ inherits this capacity) handles 'strings'.
Ok so because the remove function cant handle strings we need to convert our strings to chars to use it?
yes, looks like.

do you have <filesystem>?
https://en.cppreference.com/w/cpp/filesystem/remove
that is built from an unnecessary path-object that is built from C++ string objects.
Last edited on
@nico. That link doesn't work as it treats the final . as part of the link! You need to have at least one white-space before/after . Try https://en.cppreference.com/w/cpp/io/c/remove

delete is part of the C library - so doesn't know anything about std::string.
Last edited on
std::filesystem::remove is part of the C++ library. https://en.cppreference.com/w/cpp/filesystem/remove

It accepts std::filesystem::path and therefore we can pass std::string or std::string_view
(or for that matter any sequence of characters) to it.
https://en.cppreference.com/w/cpp/filesystem/path/path
So it would be better to use the <filesystem> header and use remove from there? Because we are working in c++. And then i would not need to make the string to a char array?
When writing new C++ code using newer standard C++ constructs and libraries is a good idea.

Although also knowing the C library as well as older C++ standards is also a good thing because it makes understanding and maintaining older code that works less of a headache.

Updating older code to a newer standard is a great learning/intellectual exercise, just don't do it on production code unless the company wants it.
I have looked at <filesystem> remove / remove all and I am not sure how its should be implemented.

1
2
3
4
5
6
7
8
9
10
    void eraseUserC() {
    std::string username;
    std::cout << "Which file do you want to erase? (Case sensitive)" << std::endl;
    std::cin >> username;
    
      if(bool remove(const username + ".txt")){
        std::cout << "File succesfully removed." << std::endl;
      }
      else std::cout << "Error, file could not be found or removed" << std::endl;
    }


This gives me error "A function type is not allowed here" I am trying to use the documentation.
bool does not belong on line 6, nor does const.
those are part of how it is defined, but not seen when you *use* it.
Last edited on
I would appreciate a short code example.

If i understand correctly remove is a function, so why do i need to define it?
Your latest code snippet defines a standalone function named remove. You simply USE std::filesystem::remove.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
#include <fstream>
#include <filesystem>
#include <string>

int main()
{
   std::string fname{ "dummy" };

   // let's create a file and put some data in it
   std::ofstream ofile(fname + ".txt");
   ofile << "Some text";
   ofile.close();

   // let's read the file and display the contents
   std::ifstream ifile(fname + ".txt");
   std::string str;
   std::getline(ifile, str);
   ifile.close();

   std::cout << str << "\n\n";

   // let's try to remove the file created earlier
   if (std::filesystem::remove(fname + ".txt"))
   {
      std::cout << "File removed....\n";
   }
   else
   {
      std::cout << "File doesn't exist!\n";
   }
}
Some text

File removed....
Thank you. It worked but the compiler gave me a error and a fix. In the end the code looked like.

1
2
3
4
5
6
7
8
9
10
void eraseUserC() {
    std::string username;
    std::cout << "Which file do you want to erase? (Case sensitive)" << std::endl;
    std::cin >> username;
    if(std::__fs::filesystem::remove(username + ".txt")){
        std::cout << "File succesfully removed." << std::endl;
    }
    else std::cout << "Error, file could not be found or removed" << std::endl;
    
}


what does the fs do?
You are combining code snippets into a royal mess. That fs crap is from namespace fs = std::filesystem;, a way of reducing key-strokes. Did you notice I don't use it?

Just fully qualify the std::filesystem::remove function, as I did.

OR use the namespace qualifier and call the function as if (fs::filesystem::remove(username + ".txt"))

If that use of namespace confuses you DON'T USE IT.

It doesn't confuse me, though I still won't use it.

Trying to save a couple of keystrokes by all these namespace short-cuts can be a huge source of errors as you've discovered. I learnt this lesson the HARD WAY.
I performed these operations but different way, the following method I'm using..

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include<iostream>
#include<fstream>
#include<stdio.h>  // rename, remove
using namespace std;

int main() 
 {
   char name[20],filename[20],newname[20];

/*create filename*/
    cout<<"Enter file-name to create: ";
    gets(filename);
    ofstream fout(filename);

/*save record into file*/
    cout<<"\nEnter a name to store in it: ";
    gets(name);
    fout<<name;
    fout.close();
    cout<<"\nrecord saved into file called - "<<filename<<endl;

/*rename file*/
    cout<<"\nHit to Rename this file";
  
    cout<<"\nEnter new name: ";
    gets(newname);
    rename(filename,newname);
    cout<<"\nNow file name is: "<<newname<<endl;
/*remove file*/   
    cout<<"\nHit to remove file\n";

    remove(newname);
    cout<<"\nfile removed successfully...";
   
 }

OUTPUT

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Enter file-name to create: database

Enter a name to store in it: rahul

record saved into file called - database

HIT ENTER to Rename this file
Enter new name: file

Now file name is: file

HIT ENTER to Remove file

file removed successfully...

Topic archived. No new replies allowed.