Shantykoff
Shantykoff

Reputation: 1

C++ Fstream Output doesn't work

Can somebody tell me why this isn't working? This thing just doesn't want to write data to a file. Input is fine. fout.open("Dats.txt", std::ios::out | std::ios::app); doesn't work either.

std::ifstream fin;
std::fstream fout;

fin.open("Dats.txt");
fout.open("C:/Users/Shantykoff/Documents/visual studio 2017/Projects/Input_Output_fstream_basis/Input_Output_fstream_basis/Dats.txt",
          std::ios::out | std::ios::app);

The problematic piece of code:

void inputData() {
    Data temp;
    std::cout << "Inserisci x\n";
    std::cin >> temp.x;
    fout << temp.x << "\n";
}

Upvotes: 0

Views: 2279

Answers (1)

Francis Cugler
Francis Cugler

Reputation: 7905

In this section of your code:

void inputData() {
    Data temp;
    std::cout << "Inserisci x\n";
    std::cin >> temp.x;
    fout << temp.x << "\n";
}

The last line you have a variable named fout that has local scope to this function that isn't declared anywhere in this block of code or within this scope. You have two options to resolve this, unless you are declaring this object in global scope outside of the main function in which you have not specified:

  • You can create an std::ofstream temporary object within this function but you would have to open & close the file stream.
  • Or you can pass an ofstream object by reference to this function.

I'll show an example of each:

void inputData() {
    Data temp;
    std::cout << "Iserisci x\n";
    std::cin >> temp.x;
    std::ofstream fout;
    fout.open( /* filename & path */ );
    fout << temp.x << "\n"; 
}

Or

void inputData( std::ostream& out ) {
    Data temp;
    std::cout << "Iserisci x\n";
    std::cin >> temp.x;
    out << temp.x << "\n";
}

Then in the code block that is invoking this function you can do...

{
    //... some other code
    std::ofstream fout;
    fout.open( "path & filename", flags );
    inputData( fout );
    fout.close();

    //... some other code
 }

If you noticed closely in this function I passed a reference to a std::ostream object instead of a std::ofstream object. Why did I choose to do this? It is simple because this function can now take any output stream type object instead of just an output file stream object...

{    
    inputData( std::cout ); // will now print to console out
    std::ostringsream ostr;
    inputData( ostr ); // will now populate the output string stream object

    // etc...
}

Basically put this line of code: fout << temp.x << "\n"; in your function above the fout object is not declared or defined in the scope of this code block unless if fout is in the global namespace outside of the main function.


Edit - Optional but as a side note with this line of code:

fout.open("C:/Users/Shantykoff/Documents/visual studio 2017/Projects/Input_Output_fstream_basis/Input_Output_fstream_basis/Dats.txt",
      std::ios::out | std::ios::app);

What I'll typically do since you are using visual studio is this:

Under the current project settings in your solution explorer:

  • Under Configuration Properties - for current config & platform settings
    • General
      • Output Directory: set to - $(SolutionDir)"ProjectName"\_build\
    • Debugging
      • Working Directory: set to - $(ProjectDir)_build\

Note: "ProjectName" is just a place holder for the actual name of the project.

Then this way you don't have to specify your entire path from the root directory C:\

Then in your code when you have files such as this:

sample.txt - placed in the _build folder where the executable will now reside instead of "visual studio's" default location.

1 2 3 4 5 6 7 8 9

main.cpp

int main() {
    std::vector<unsigned> values;

    std::ifstream in;
    unsigned val;
    in.open( "sample.txt" );
    while ( in >> val ) {
        values.push_back( val );
    }
    in.close();

    // lets modify some values
    for ( auto v : values ) {
        v *= 10;
    }

    // Let's print new values to same file but lets append it to a new line
    std::ofstream out;
    out.open( "sample.txt", std::ios::app );
    for ( auto v : values ) {
        out << "\n";
        out << v << " ";
    }
    out.close();

    return 0;
}

sample.txt

1 2 3 4 5 6 7 8 9
10 20 30 40 50 60 70 80 90

Now by creating a _build folder within the solution explorer it makes the reading of code for long paths easier to read since the paths are now relative to the project's directories and should be pointing to the same folder that will contain the applications executable as well as any third party dependencies - external dlls. Now as for myself I chose to place an single underscore in the front of the build folders name only to keep it towards the top of its parent directory.

Upvotes: 1

Related Questions