I am just starting out with c++, but I have a goal in mid. I have already programmed the logical portion of what I wish to acomplish in Java, but it doesn't work, because I can't set a usb to read only for the whole system in Java (if I can;t do this in c++ then tell me now). I have this code and it can read the file fine, but when I write to it and then open the file it doesn't actually write to the file.

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main()
{
    fstream myFile ("C:/Test/C++FileRW/test.txt");
    string line;        

    if (myFile.is_open()){
        getline (myFile, line);

        cout << line << "\n";
        myFile << "\nExtra Text Added";
        cout << "Wrote to file";
        myFile.close();
    }else {
        cout << "Unable to open file";
    }

    cin.ignore(1);

    return 0;
}

This should either append the Extra Text Added, or it should replace the original text, but it doesn't do either of those. What is the problem, and how can I fix it?

Thank you for your help.

Edited 3 Years Ago by sirlink99

As an aside, this will fail if the file does not exist when an attempt is made to open it.

Try specifying the open mode when you open it:
fstream myFile ("C:/Test/C++FileRW/test.txt", std::ios::in | std::ios::out);

Edited 3 Years Ago by Moschops

Whenever you want to you fstream as for both input and output operations, you have to explicitly say it when you open a file.
Have a look at a tutorial posted a while on daniweb Click Here

So, to be of any service, change this in your code:

fstream myFile ("C:/Test/C++FileRW/test.txt");
string line;        

to

fstream myFile;
myFile.open("C:/Test/C++FileRW/test.txt", ios::in|ios::out|ios::app); //this will open the file for both input/output and
                                                                      //append mode
string line;        

@Moschops: I do believe that opening a fstream file like this:

fstream myFile ("C:/Test/C++FileRW/test.txt", std::ios::out);

will erase everything from the file (such as the fopen(filename, "w"); in C)

Edited 3 Years Ago by Lucaci Andrew

It doesn't on the system I did a quick test run on, but to be honest I'd have to go back and read the standard to be sure what should happen; file IO often seems to stray from the strict standard in my experience. It's the kind of thing I usually use a bigger library for :(

Edited 3 Years Ago by Moschops

Yeah, well, I use MinGW on the last tests, and indeed, opening the file only with the std::ios::out flag will open it for writing, that is if the file exist, will clean up the file, or if the file doesn't exist, will create a new one.

I'm guessing that opening a file in both std::ios::out and std::ios::app will do the trick, that is, if the file doesn't exist, it will create one, or if the file exists, will open it, and will place the cursor in the file, at the last character.

@Moschops I have already made the file, as I have stated I could read from it.

I have tried both your suggestions and adding the ios::in | ios::out | ios::app did not fix the problem. I also tried fstream::in | fstream::out as was suggested by the first link posted by Andrew, but that didn't fix the solution either. I added in another if statement after the readLine which checks if the stream is ready to write using the bad() function. This shows that the read works (as can be seen), but when trying to write the if statement executes (returns true) which according to the c++ documentation means that the write operation failed which is reflected in the line not appearing in the file.

Here is my new code

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main()
{
    fstream myFile;
    myFile.open("C:\\Test\\C++FileRW\\test.txt", ios::in | ios::out | ios::app);
    string line;        

    if (myFile.is_open()){
        getline (myFile, line);
        cout << line << "\n";
        if (myFile.bad())
            cout << "Read Failed";
        myFile << "\nExtra Text Added \n";

        if(myFile.bad())
            cout << "Write Failed";
        else
            cout << "Wrote to file \n";
        myFile.close();
    }else {
        cout << "Unable to open file";
    }

    cin.ignore(1);

    return 0;
}

Thanks for the help

Edited 3 Years Ago by sirlink99

Well, than I suggest you to try using specific streams for each operations, e.g. ifstream for reading from files, and ofstream for writing to files.
Here's something to explain a bit what I'm trying to say:

#include <fstream>
#include <iostream>
#include <string>
using namespace std;

int main(){
    string filename = "a.txt";
    ifstream fin (filename.c_str(), ios::in);        // reads from the file
    ofstream fout (filename.c_str(), ios::app);      // opens the file in append mode

    if (fin.good()){                                 // checks whether the stream is good to be read from
        string line;
        getline(fin, line);                          // get the 1st line
        cout<<line<<endl;                            // print it
        string textToAdd = "\nNew text was added.\n";
        fout<<textToAdd;                            // write something to file
    }

    return 0;
}

For a detailed view over ifstream: Click Here
and for ofstream: Click Here

Edited 3 Years Ago by Lucaci Andrew

Using two separate streams solved the problem. Also I hid a small question in the original post. Is it possible to set a file to read only for the whole system using c++, or an alternative is to safely eject a usb drive if it does not meet certain conditions?

Another questions is there anything that could go wrong and corrupt a file by having both an input and an output stream open at the same time?

Thanks for the help.

Hi, as you are working with files and external devices i would suggest you use flush on your writing stream http://www.cplusplus.com/reference/ostream/ostream/flush/ .This should force data to be written from any memory buffers to the file. However i could not say for sure because of the nature of usb / flash devices if the physical device is fully updated.

For example when you copy a large file to a usb disk the OS will say its done, but it hasnt actually finished writing the data to the physical device yet which is why we need things like safely remove device.

To ensure the data is fully flushed to the USB device i dont know how to do that in C/C++ but i would imagine its very OS specific.

Edited 3 Years Ago by Kanoisa

This question has already been answered. Start a new discussion instead.