I want to access a text file in a C-like fashion. The option CARRIAGECONTROL= 'NONE' apparently achieves this, according to this page. Is it a standard option ?
If by "C-like fashion" you mean read the file as a stream of bytes, there was no standard way to do this before Fortran 2003. However many compilers offered it as an extension, like the manual of the Intel compiler on the webpage you refered to.
Since Fortran 2003, there is a standard way of opening a file for stream access which is
ACCESS='STREAM'
The standard option is access='stream' in the open statement
In F77, this was not standardized and often compiler dependent.
Related
I have found several questions and answers about this, but among "stream", "recl", HDF,etc. I am a bit lost ( I am quite a newbie ).
I apologize if there is somewhere a plain answer to my question.
This is my problem: I want to insert into an existing Fortran code a "WRITE" statement that produces an unformatted file that I can subsequently read with another post-processing Fortran code that I have written. With portability I mean that I can do this regardless the compiler and compilation flags used and, ideally, between different platforms (computers). Is this possible? How? If not, what are the compromises that I must accept?
If the anwer is supported by a detailed, but not too complicated, explanation, it would be highly appreciated.
p.s.
I want to use unformatted files because they are lighter and the I/O operations should be faster than with formatted files. Correct?
Update #1
From a comment it seems that it is not strictly possible to obtain an unformatted file which is portable to different machines. Therefore, let us assume I want to use a single machine. I am using ifort and gfortran. If with Fotran90 is not possbile, I think I can use Fortran2003. For me it is a bit complicated to control the compilation flags used to compile the original code, but if it is necessary I can work to control that aspect too.
How can I deny access to a file I open with fstream? I want to unable access to the file while I'm reading/writing to it with fstream?
You cannot do it with the standard fstream, you'll have to use platform specific functions.
On Windows, you can use CreateFile() or LockFileEx(). On Linux, there is flock(), lockf(), and fcntl() (as the previous commenter said).
If you are using MSVC, you can pass a third parameter to fstream's constructor. See the documentation for Visual Studio 6 or newer versions. Of course it won't work with other compilers and platforms.
Why do you want to lock others out anyway? There might be a better solution...
Expanding on the comment by Casebash:
To open a file in windows so that other processes cannot write to it use
file.rdbuf()->open(path, std::ios_base::app, _SH_DENYWR);
_SH_DENYRW will deny both read and write access
There is no way to do this in native C++, as it would be highly platform dependent. On Linux/UNIX, you can do this with flock or fcntl. I'm not really sure how to do it on Windows.
On windows, it looks like you have to pass some flags to CreatFile or use LockFileEx (which allows byte range locking).
Note that, all of these methods work on the underlying OS file descriptors/handles, not with fstreams. You will either need to use the Posix or Windows API to read/write from the file, or wrap the file descriptor/handle in an fstream. This is platform dependent again. I'm sure there is a way to do it, but I don't remember it off the top of my head.
Is there a similar function to Turbo Pascal's assign(out f:file, const Name) function which assigns a name to a file in c++ without opening the file?
Pascal has an older language construct where you “bind” identifiers to external system resources. Borland (Turbo Pascal) never really implemented the concept beyond what you find in the file access routines.
Most modern languages follow the C-style methodology, in large part because almost all modern operating systems follow the Unix-style file/character device/etc design.
Either way, ask yourself what exactly you are trying to accomplish, then figure out how to do it using idiomatic C++. The C++ way really is more straightforward.
As you can see, C++ does not have a way in the standard library to create a file stream, give it a file name and then open it. The open action uses a file name.
You can create an file stream that is not open yet, but it won't have a file name.
I have seen this annoying question again and again. Could you please share your knowledge that might help us to find the answer.
My confusion is that, forward-slash is posix standard but directory structure of operating systems are different.
Thank you
What is the correct syntax for portable fstream file paths?
(e.g. the string you would pass to std::fstream:open() to open a file.)
A. "::directory:file.bin"
B. "C:/Directory/File.bin"
C. "/directory/file.bin"
D. "C://Directory//File.bin"
E. std:fstream file paths are not portable.
E : not portable, i.e. implementation defined
Answer can be found in the std::fopen docs: (which are referred to by fstream via filebuf::open)
Notes
The format of filename is implementation-defined, and does not
necessarily refer to a file (e.g. it may be the console or another
device accessible through filesystem API). On platforms that support
them, filename may include absolute or relative filesystem path.
What you and many of the rest of us are eagerly awaiting is the FileSystem Technical Specification: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4099.html
It is largely an import of boost/filesystem into the C++ standard.
The technical specification has been made available as part of C++'s experimental section. However, that isn't implemented by default in gcc 4.9.2 or Visual Studio 2013.
Here's to hoping it's coming soon!
You can see more information here: http://en.cppreference.com/w/cpp/experimental/fs
What you are specifically looking for is path: http://en.cppreference.com/w/cpp/experimental/fs/path
By way of answering your problem in the now though if you're looking to do this you need to use #ifdefs and implement your code per target platform.
(E) - there is no portable standard, as different filesystems and Operating Systems have different expectations and restrictions. fstreams don't restrict you to the minimum always-supported subset of all actual implementations, or you'd only be able to write "8.3" filenames to the current working directory ;-P
That said, if you're interested in this "problem space", you'll probably want to check out the boost filesystem library, which is not Standard, but is at least widely known....
Paths are not portable. It is futile to try to use a portable syntax, since any that you come up with may not be portable between future filesystems. However, it should be possible to do one of the following:
Design your application so that you do not need to store paths.
Use your own path format which you can covert into paths on the current system.
Restrict the paths that your application uses to a portable (between Windows/Linux) subset (e.g: relative paths with "/" as path separator)
Store multiple versions for the same path and use the correct one on each supported OS.
Store one form of paths (e.g. Linux paths) and use a simple scheme to convert to e.g: Windows paths. Document this scheme so that the user understands how paths are interpreted.
I wrote more on this here: https://stackoverflow.com/a/40980510/2345997
When a stdio stream encounters an error (but not EOF), the stream's error indicator will be set so that ferror() will return nonzero. I have always assumed that more information is available in errno. But how do I know this?
Documentation for some functions [e.g. man fopen under Linux] says that errno will also be set. However man fgets doesn't mention errno at all. The glibc info pages are reassuring:
In addition to setting the error indicator associated with the
stream, the functions that operate on streams also set `errno' in the
same way as the corresponding low-level functions that operate on file
descriptors.
But I have no idea how strong this guarantee is. Is it required by the C standard? What happens in Visual C/C++?
The C Standard itself does not require much use of errno WRT to stdio functions; it specifies ferror() but says of it only that
7.13.10.3 The ferror function The ferror function tests the error indicator for the stream pointed to by stream. The ferror function returns nonzero if and only if the error indicator is set for stream.
from the C99 Draft: http://www.vmunix.com/~gabor/c/draft.html. Any actual error codes used are, for the most part, implementation defined.
However, the GNU C library on linux also conforms to POSIX specifications:
http://pubs.opengroup.org/onlinepubs/9699919799/toc.htm
Which are much more well defined in this context. For example, if you look at the page for fopen:
http://pubs.opengroup.org/onlinepubs/9699919799/functions/fopen.html
You'll see a lot of detailed information, including specific errno codes, under Errors.
Again, the GNU C library used on virtually all normal linux systems is POSIX compliant, so you can count on that information ;). Those (online) POSIX man pages are also generally more detailed than the standard linux system man pages (read both).
WRT to file operations on other (non-POSIX) platforms, they will have their own implementations. Unfortunately, stuff like that is not transparently portable in standard C. C++ streams do have more standardized error handling, though.
According to the C11 standard, chapter 7.21 ("stdio.h"), only fgetpos, fsetpos and ftell write to errno in the event of an error.