C vs C ++ file processing

I worked in C and C ++, and when it comes to processing files, I get confused. Let me state what I know.

In C, we use functions:

  • fopen, fclose, fwrite, fread, ftell, fseek, fprintf, fscanf, feof, fileno, fgets, fputs, fgetc, fputc.
  • FILE * fp for a file pointer.
  • Modes such as r, w, a

I know when to use these functions (I hope I have not missed anything important).

In C ++, we use the / operator functions:

  • fstream f
  • f.open, f.close, f →, f <, f.seekg, f.seekp, f.tellg, f.tellp, f.read, f.write, f.eof.
  • Modes like ios :: in, ios :: out, ios :: bin, etc.

So, is it possible (recommended) to use C-compatible file operations in C ++? What is more widely used and why? Is there anything else besides this that I should know about?

+5
source share
3 answers

Sometimes there is existing code waiting for one or the other that you need to interact with, which may affect your choice, but in general C ++ versions would not be introduced if there were no problems with C versions that they could fix. Improvements include:

  • RAII semantics, which means, for example, fstream to close the files they manage when they leave the area

  • modal ability to throw exceptions when errors occur that can make for cleaner code focused on typical / successful processing (see http://en.cppreference.com/w/cpp/io/basic_ios/exceptions for the function and example API)

  • security type, so how input and output is executed is implicitly selected using the variable type used

    • C-style I / O has the potential for failures: for example, int my_int = 32; printf("%s", my_int); int my_int = 32; printf("%s", my_int); , where %s tells printf expect a pointer to the ASCIIZ character buffer, but my_int appears my_int ; firstly, an agreement on passing arguments can mean that int are passed differently to const char* s, secondly, sizeof int may not equal sizeof const char* , and finally, even if printf retrieves 32 as const char* in the best case, it will simply print random garbage from memory address 32 until it accidentally rubs the NUL character - it is much more likely that the process will not get permission to read some of this memory, and the program will crash. Modern C compilers can sometimes check the format string for arguments provided, reducing this risk.
  • extensibility for custom types (i.e. you can teach threads how to handle your own classes)

  • support for dynamically determining receiving strings based on actual input, while C functions typically need hard-coded maximum buffer sizes and loops in user code to build an arbitrary input size

Streams are also sometimes criticized for:

  • formatting verbosity, in particular, the width of the "settings", "precision", "base", "addition" compared to printf format strings

  • sometimes a confusing combination of manipulators that save their settings in several I / O operations and others that reset after each operation

  • there is no convenience class for RAII, pressing / saving and subsequent ascent / restoration of the state of the manipulator

  • slow since Ben Voigt's comments and docs are here

+10
source

The performance differences between formatting print / input / output streams of the printf() / fwrite style of I / O and C ++ are very implementation dependent.

Some implementations (for example, Visual C ++) create their input-output streams on top of FILE * objects, and this, as a rule, increases the complexity of their execution at runtime. Please note, however, that there were no particular restrictions for implementing the library in this way.

In my opinion, the benefits of C ++ I / O are as follows:

  • Enter security.
  • Flexibility of implementation. Code can be written to perform certain formatting or input to a generic or <generic ostream or istream . The application can then call this code with any derived streaming object. If the code that I wrote and tested against the file now needs to be applied to a socket, serial port, or some other internal stream, you can create a stream implementation specific to this type of I / O. Extending C style I / O this way doesn't even come close to the possibilities.
  • Flexibility in locale settings: C's approach to using a single global language, in my opinion, is seriously spoiled. I had cases when I called the library code (DLL), which changed the global locale settings under my code and completely ruined my output. With a C ++ stream, you can imbue() bind any object to a stream object.
+3
source

An interesting critical comparison can be found here.

C ++ FQA io

Not very polite, but makes you think ...

Renouncement

C ++ FQA (this is a critical answer to frequently asked questions about C ++) is often viewed by the C ++ community as "a stupid joke issued by a stupid guy who doesn't even understand what C ++ is or wants to be" (cit. From FQA itself )

These arguments are often used to flame (or exit) religious battles between C ++ believers, other languages, believers or linguistic atheists, each in their own humble opinion, convinced to be superior to the other.

I'm not interested in such battles; I just like to stimulate critical discourse about the pros and cons. C ++ FQA - in this sense - has the advantage of placing both FQA and FAQ one on top of the other , which allows you to immediately compare. And this is the only reason I referred to her.

Following the TonyD comments below (tanks for them, I make it clear that my intention needs clarification ...), it should be noted that the OP does not just discuss << and >> (I just talk about them in my comments just for brevity) but the whole set of functions that make up the C and C ++ I / O model.

With this idea in mind, think of other “imperative” languages ​​(Java, Python, D ...), and you will see that they are more and more consistent with the C model than C ++. Sometimes this even makes the type safe (that the C model is not, and that its main drawback).

What is my point about

At a time when C ++ appeared as the main one (1996 or so), the library <iostream.h> (note the ".h": pre-ISO) was in a language where templates that are not yet fully accessible, and, in essence, the "strong" safe support for varidic functions (we need to wait until C ++ 11 receives them), but with overloaded types of functions .

The idea of ​​oveloading << reconfiguring its first parameter again and again is actually a way to bind a variable set of arguments using only a binary function that can be overloaded in a safe manner. This idea extends to any “state management function” (for example, width() or precision() ) using manipulators (for example, setw ) as a natural consequence. These points, despite the fact that you can tell the author of the FQA, are real facts. And also the fact that FQA is the only site I have found that talks about it.

However, years later, when the D language was developed, starting to offer varadic patterns, the writef function was added to the standard D library, which provides the printf syntax, but is also completely type safe. (see here )

C ++ 11 currently also has varadic templates ... so the same approach can be put in exactly the same way.

Moral of history

Both C ++ and C io models look "obsolete" in relation to the modern programming style. C keep speed, security at the C ++ level and a “more flexible abstraction for localization” (but I wonder how many C ++ programmers in the world know about locales and faces ...) when it takes time (track jut with debugger <number number, passing stream, language standard and facet ... and all the virtual functions associated with it!).

Model C can also be easily expanded to parametric messages (the order of the parameters depends on the localization of the text in which they are located) with format strings such as

@ 1% d @ 2% i, which allows you to create scripts like "text @2%i text @1%d ..."

The C ++ model does not have the concept of a “format string”: the order of parameters is fixed and marked with text.

But C ++ 11 varadic templates can be used to support:

  • can offer both local selection of compilation time and runtime
  • may offer a parametric order of compilation time and runtime
  • may suggest a compilation type parameter type
  • ... everything using a simple form methodology.

Is it time to standardize the new i / o C ++ model?

0
source

Source: https://habr.com/ru/post/1202832/


All Articles