How to refresh an input file stream in C++ - c++

I am writing a program that monitors for changes in a file for a specific purpose. The possible values (3) in the file are known and can be differentiated by the first letter.
Using an input file stream ifstream status;, I'm unable to refresh the buffer of the input stream status to reflect changes in the file. I don't want to spam status.close() and status.open() to solve the problem.

If the changes you mentioned include only appended bytes, then you can use the std::ifstream::clear() to clear any error bit and continue reading the file until reaching the EOF. Check out this answer.

Related

preferred c++ i/o stream method: fstream or ifstream/ofstream or something else entirely?

I have created a roster program that accepts user input to create/write/delete information into and out of a specified text file. My issue now becomes wanting to create a lasting text file that isn't overwritten every time I re-run the program and am not sure if using fstream or a combination of of/ifstream is better practice, or if there is maybe a third option I missed when checking the reference docs.
Right now I am simply using: std::ofstream outfile("roster.txt"); which works, until I kill and re-run the program to which my text file is now wiped clean.
check out the append flag. it writes to the end of an existing file.
http://www.cplusplus.com/doc/tutorial/files/
example here.
std::ofstream outfile("roster.txt" , ios::app)

Problems getting ftell() in binary append

I've got some code that was working on a server until it was moved to a different system. The problem seems to be here:
given a structure I've defined elsewhere:
user1_type user1; /* structure containing user data */
user1_type *user1_ptr=&user1;
this routine appends the record to the end of the file
if ((dfile=fopen(filename,"ab+"))==NULL)
error_message("Unable to open file for append.",filename,1);
else { /* append data */
user1.recid=ftell(dfile); /* update file position */
fwrite(user1_ptr,sizeof(user1),1,dfile);
fflush(dfile);
fclose(dfile);
I can confirm the data gets appended in the file, but the value of user1.recid always returns 0 - any ideas why?
UPDATE: Looks like the issue is not all implementations require a fseek() after fopen(). I obviously need an fseek(dfile,0,SEEK_END); before I do a ftell() when appending. But if I want to read from the beginning of a text or binary file, is it also customary to place a fseek() right after fopen? Does it vary depending upon the file type?
From MSDN's documentation of ftell
The position returned by ftell() is expressed as an offset relative
to the beginning of the stream
If no I/O operation has yet occurred on a file opened for appending,
the file position is the beginning of the file.
This gives you an offset of 0 relative to the beginning.
So when you call user1.recid=ftell(dfile); no I/O operation has occurred on the stream yet so ftell() returns 0 indicating the file pointer position is at the begining.
This behavior of ftell(dfile) here would be implementation defined. From C11 7.21.3 (similar wording in previous C standards):
If a file can support positioning requests (such as a disk file, as
opposed to a terminal), then a file position indicator associated with
the stream is positioned at the start (character number zero) of the
file, unless the file is opened with append mode in which case it is
implementation-defined whether the file position indicator is
initially positioned at the beginning or the end of the file.
...so (in addition to bkVnet's answer) you must use fseek(dfile,0,SEEK_END) to seek to the end, ask ftell the position and divide that by sizeof(user1_type) to get the record id (i.e. the number of records already in the file, so plus 1 for the new record).

How to leave a file open and continue from where we left last time? C++

Is there is a way to read in from a file until the end of a line, then go to another function do something, then come back afterwards to read in from the same file BUT from where we stopped last time (not from the beginning of the file)?
If yes, please provide a snippets. Code makes more sense to me than words. Thanks
When opening a file for writing using std::fstream::open(), you have the options to set the file openmode as the second argument after the filename...
std::fstream file;
file.open("myfile.txt", ios_base::openmode::ate);
openmode::ate is the flag used to open the file with the input cursor positioned at eof.
http://www.cplusplus.com/reference/ios/ios_base/openmode/
http://www.cplusplus.com/reference/fstream/fstream/open/
http://www.cplusplus.com/reference/fstream/fstream/

std::ofstream open file and replace in specific offset

I want to open a file (without re-creating it) and write to a specific offset.
This is the current code :
std::ofstream file(conf_file_path, std::ios::app);
file.seekp(offset, std::ios::beg);
const auto& output = file.write(conf_str, conf_str_len);
But it always writes to the end of file (probably due to the app flag)
If I don't use the app flag, it re-creates the file as I open it.
How can I open it without re-create it and be able to write to specific offset ?
it always writes to the end of file (probably due to the app flag)
Yes, this is due to the app flag. Here's what the documentation says:
app - seek to the end of stream before each write
If I don't use the app flag, it re-creates the file as I open it.
If you have out or trunc flags sets in the mode, then it destroys the contents of the file, if it already exists.
How can I open it without re-create it and be able to write to specific offset ?
You may use in|out. This will error out if the file doesn't exist; if it exists, the file will be opened and read from the beginning. If you want the stream to be read from the end, you may set the ate flag additionally.
All of this is clearly documented here; reading the manual really helps.

Reading file contents using with statement

I'm fairly new to Python, so I haven't done much in the way of reading files.
My question is this: if I use
with open(sendFile, 'r') as fileContent:
response = fileContent.read()
will the whole file always be read in to response at once or is there any chance that I'd have to call read() multiple times? Or does read() just handle that case for you?
I believe the file will be closed after this call, so I just want to make sure that I'm getting the whole file and not having to go back, open it again, and read more
Unless you specify a size, the read method reads the whole contents of the file.
From https://docs.python.org/2/library/stdtypes.html#file.read :
If the size argument is negative or omitted, read all data until EOF is reached.