2

I want to edit a textfile with multiple lines. In every line I want to remove the first character if it's a space.

I have found multiple examples with ifstream and ofstream. But there, input and output file are different files.

But I want input and output to be the same file but I can't figure out if and how fstream works.

    fstream file;
    file.open(path, ios::in | ios::out);

     while (getline(file, line))
     {
           if (line[0] == ' ')
           {
                line.erase(0, 1);
           }
           file << line << "\n";
     }

So far the code doesn't change anything in my file.

Thanks for for the help.

M. Keller
  • 41
  • 3
  • 1
    editing a file *in-place* can be delicate work, consider reading in the whole file (probably into a vector of strings), modifying it, and then writing it out. – kmdreko Oct 24 '17 at 07:45
  • Another hint: It is often handy to combine a program and the operating system's facilities. While e.g. gnu sed has an `--inplace` option which I have put to good use, it wouldn't be uncommon to use standard `sed` just writing to stdout and *redirect the output with the help of the operating system*. When one is happy with the result one can then simply overwrite the old file with the new file. E.g. `sed 's/^ .*//g' some.txt > tmp.txt && mv tmp.txt file.txt`. The reason is that file handling is done very well by the OS shells already, and writing to stdout is surprisingly more versatile. – Peter - Reinstate Monica Oct 24 '17 at 08:07
  • As to the subject at hand (this is a correction to an earlier post): Currently you are not writing back to the file at all. You probably want to store the file in memory (using @vu1p3n0x's suggestion), modify it, and then write it back to the file on disk. I suppose that the easiest method to re-write the file is to close the input stream and re-open it for writing with the `trunc` option, as suggested [here](https://stackoverflow.com/a/24189274/3150802). My earlier suggestion to use `seekg` would not truncate the file but only overwrite the beginning (you have fewer lines than the original). – Peter - Reinstate Monica Oct 24 '17 at 08:13
  • If you want a portable solution then you should employ two files (or a temporary file). If not, you can use the [fstream::seekp](http://en.cppreference.com/w/cpp/io/basic_ostream/seekp) to position yourself where you want and overwrite the file content. – Ron Oct 24 '17 at 08:14
  • @PeterA.Schneider the easiest methd is the most dangerous. If your program crashes, you lose the file. The safe way is to save to a different file, remove the original, then rename the new file. – n. m. could be an AI Oct 24 '17 at 09:55
  • @n.m. True; the thing is this will only be portable in C++17. That's why I suggested to use the OS. – Peter - Reinstate Monica Oct 24 '17 at 10:00

3 Answers3

2

Thanks for your help! I have saved everything in a vector as vu1p3n0x suggested. Also I removed namespace (just in case) and I will do this in my future programs as well. I have never considered that so thanks to tambre.

I think the code is far from perfect but here it is in case someone needs it.

            std::ifstream filein;
            std::string line;
            filein.open(help);
            std::vector<std::string> temp;

            while (std::getline(filein, line))
            {
                if (!line.empty())
                {
                    if (line[0] == ' ')
                    {
                        line.erase(0, 1);
                    }
                }
                temp.push_back(line);
            }
            filein.close();

            std::ofstream fileout;
            fileout.open(help, std::ofstream::out, std::ofstream::trunc);

            int l = 0;
            while (l < temp.size())
            {
                //cout << temp[l] << "\n";
                fileout << temp[l] << "\n";
                l++;
            }
            fileout.close();
M. Keller
  • 41
  • 3
0

So far the code doesn't change anything in my file.

You problem is that you are modifying the line (which I presume is just a string), but not writing it back to the file

Werner Erasmus
  • 3,988
  • 17
  • 31
-2

You can do it with two files:

// TODO: error checking!
fstream file1;
file1.open(path1, ios::in);
fstream file2;
file2.open(path2, ios::out | ios::trunc);

 while (getline(file1, line))
 {
       if ( !line.empty() && line[0] == ' ' )
             file2 << line.substr( 1 ) << "\n";
       else
             file2 << line << "\n";
 }

 file2.close();
 file1.close();

Or use ostringstream.

// TODO: error checking!
fstream file;
file.open(path, ios::in);
ostringstream osstream;

 while ( getline( file, line ) )
 {
       if ( !line.empty() && line[0] == ' ' )
             osstream << line.substr( 1 ) << "\n";
       else
             osstream << line << "\n";
 }

 file.close();
 file.open( path, ios::out | ios::trunc );
 file << osstream.str();
 file.close();
Daniel Sęk
  • 2,504
  • 1
  • 8
  • 17