1

I've been trying to write a program to open a file in both read and write mode:

#include <fstream>
#include <iostream>
using namespace std;
int main(){
    fstream obj;
    obj.open("hello.txt",ios::in|ios::out);
    if (!obj){
        cout << "File not opened" <<endl;
        return 1;
    }
    obj << "Hi How are you" ;
    char c;
    while (!obj.eof()){
        obj.get(c);
        cout << c;
    }
    obj.close();
    return 0;
}

When I compile this program on Visual Studio Code on Windows, though the text "Hi how are you" is printed in the file, the contents of the file are not printed on my screen. Can someone tell me what might be the problem?

John Kugelman
  • 307,513
  • 65
  • 473
  • 519
proglove
  • 25
  • 5
  • 1
    Preferably open the file in binary mode. And do `obj.seekp(0)` after writing to it and before reading. You may also want to read up on why `while(!obj.eof())` is often inadvisable. – Peter Apr 23 '21 at 06:54
  • The file position is always at the file end, you can't read bytes after the write operation. Also take a look at [Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-i-e-while-stream-eof-cons). – S.M. Apr 23 '21 at 06:55
  • Try putting obj.seekg(ios::beg); before where you read from the file. This resets the stream positioning to the beginning of the buffered data rather than at the end where it is after a write operation. – Jim Castro Apr 23 '21 at 06:58
  • Hey forks! Can you tell me how to modify my program in a way that I don't have to use EOF? @S.M – proglove Apr 23 '21 at 07:05
  • The question @S.M. linked explains what to use instead of `while (!obj.eof())`. – John Kugelman Apr 23 '21 at 07:07

2 Answers2

1

Resetting the position indicator with seekp to 0 helps, because both output and input indicators are set to the end of file after write operation (you can read them with tellp tellg).

obj << "Hi How are you" ;
obj.seekp(0);

char c;
while (!obj.eof()){
    obj.get(c);
    cout << c;
}

Considering avoiding using obj.eof(), you can e.g. read your file line by line:

std::string line;
std::getline(obj, line);
std::cout << line << std::endl;

or in the loop:

while (std::getline(obj, line))  // here std::basic_ios<CharT,Traits>::operator bool is used to check if operation succeeded
{
  std::cout << line << std::endl;
}
pptaszni
  • 3,794
  • 5
  • 19
  • 37
-2

You got two problems there: buffering and seek position.

Buffering: When you write the text with obj << "Hi How are you, you just write it into the buffer and the text gets written into the file after flushing the buffer. You can adjust which buffer type you want to use. The easiest way is to write std::endl after your text if you use line buffering.

A better explaination is already here

Seek Position:

You are reading from the last position in your file. You have to manually change the read position to the first character in the file, then you are done.

Bananenkönig
  • 410
  • 1
  • 9
  • Pardon me, I went through that page, but I couldn't understand you point. Can you please tell me here? – proglove Apr 23 '21 at 06:47
  • Buffering is not the problem here. Writing `std::endl` won't help. – John Kugelman Apr 23 '21 at 06:51
  • Ok I am sorry, I just tried it out and you have a second problem in your code. But first @JohnKugelman, std::endl will help, because when not writing it the text won't be in the file. The other problem is the position from where the file get's read. – Bananenkönig Apr 23 '21 at 06:56
  • 1
    Buffering affects what's visible from outside the process, but not what's visible from within the program when using a single `fstream` object. Now the read position, yes, that's where the answer lies. Change your answer to that and you're in business. – John Kugelman Apr 23 '21 at 07:03