Home c Work with binary files on SI

Work with binary files on SI




Task This: There is a binary file containing entire positive and negative numbers. From it you need to remove the biggest and the smallest. I was able to find these numbers and add to the file, but come up with them, on the contrary, to delete, I can’t work. Please help

# include & lt; stdio.h & gt;
#Include & lt; stdlib.h & gt;
#Include & lt; malloc.h & gt;
#Include & lt; String.h & gt;
#Include & lt; limits.h & gt;
/ * Changing the file according to the task * /
void edit_file (char * filename);
/ * Display the contents of the binary file on the screen * /
void Out_File (char * filename);
INT MAIN (int n_arg, char * arg [])
  System ("CHCP 65001"); // Changing the encoding if the file in the UTF-8 encoding
  System ("CLS");
  char * file_name;
  File * Fin, * Fout;
  // Read the program arguments
  if (n_arg & gt; 1) {
    file_name = (char *) malloc (SizeOF (arg [1]);
    file_name = arg [1];
  } else {
    File_Name = (char *) Malloc (SizeOf (Char) * 20);
    // If the arguments are not set to enter the file name by the user.
    // Limit on the name of the file 20 characters.
    Printf ("Enter the file name:");
    if (! FGETS (File_Name, 20, Stdin)) {
      PrintF ("\ Nonya file is entered incorrectly");
      Return 1;
    File_Name [Strlen (File_Name) -1] = '\ 0';
  PrintF ("Source File: \ N");
  Out_File (File_Name);
  edit_file (File_Name);
  PrintF ("Modified File: \ N");
  Out_File (File_Name);
  PrintF ("\ n");
  Return 0;
Void Out_File (char * FileName)
  // Conclusion of the contents of the file on the screen
  int n = 0;
  File * Fin;
  FIN = Fopen (FileName, "Rb");
  if (! FIN)
    PrintF ("Unable to open a binary file \ n");
    EXIT (0);
  While (& amp; n, sizeof (n), 1, fin))
    Printf ("% 5d", N);
  FClose (FIN);
void edit_file (char * filename)
// Changing the contents of the file
  int n = 0, max = int_min, min = int_max;
  File * Fin;
  Fin = Fopen (FileName, "R + B");
  if (! FIN)
    PrintF ("Unable to open a binary file \ n");
    EXIT (0);
  reWind (FIN);
  // We shift all items on 1
  While (& amp; n, sizeof (n), 1, fin))
    if (N & GT; MAX) max = n; // Check the maximum
    IF (N & LT; MIN) min = n; // Checking the minimum
  // Record maximum
  FWRITE (& amp; max, sizeof (n), 1, final);
  // write minimum
  FWRITE (& amp; min, sizeof (n), 1, fin);
  FClose (FIN);
  Printf ("\ N \ NFail is changed \ n");

Answer 1, Authority 100%

File operation functions do not provide for “removal” piece. The file is represented as a “inseparable tape”. In the tape you can write, you can move along the array left to the right. You can do it shorter. You need to work with the file somewhere as well as with one conventional array of char array [] without additional amenities, you can only change the length.

Since it is clearly cut off a piece of file, then “indirect” cutting is made. The following operations apply for the file. Open discovery. Close – closure. Seek – Move. Read reading. Write – recording. Trunc – Circumcision. I would single out three file overwriting algorithm.

Trunc in different systems is dug in different ways. I used _Chsize from io.h. But whatever she worked, I had to take a file descriptor using Fileno, and the current file position using Ftell. Total turned _ChSize (Fileno (F), Ftell (F)); . In WinAPI, you can use Setendoffile , Unix F-Code Ftruncate Machine.

  1. The simplest algorithm will be like this: Open, Read, processing, seek (0), Write (entire file), truncate. Those.

    # include & lt; io.h & gt;
    // ...
    File * Fin;
    Fin = Fopen (FileName, "R + B");
    // ....
    FSEEK (FIN, 0,0);
    FWRITE (new file); // write the entire buffer with new data
    _ChSize (Fileno (F), Ftell (F)); // truncate Set the file size
    FClose (F);

When recording, do not have to record all in one piece. You can put the cycle and record all the elements except the remote consistently.

  1. That would not shovel the whole file, it is possible for example to remove the line 2 of the file.
    Create a file, write to it 1 2 3 4 via a carriage return. Delete row number 2 can be so (the code is not perfect, for example, how to throw a piece of a file from on to)

    # include & lt; stdio.h & gt;
    #Include & lt; io.h & gt;
    int main (int n_arg, char * arg [])
     FILE * f = fopen ( "1.txt", "r + b"); // No checking
     char myfile [4096];
     int size = fread (myfile, 1,4096, f); // Read the entire file
     int from = 0, to = 0, i;
     // Find the first character 13
     for (i = 0; i & lt; size; i ++) if (myfile [i] == 13) {from = ++ i; Break; }
     // Search for the second character 13
     for (i = from; i & lt; size; i ++) if (myfile [i] == 13) {to = ++ i; Break; }
     if ((from = 0) & amp;! & amp; (to = 0)) {
      fseek (f, from, 0); // We leave from the beginning of the file unchanged
      fwrite (myfile + to, size - to, 1, f); // Writing the changed portion of a file
      _chsize (fileno (f), ftell (f)); // crop the old "tail"
     fclose (f);
  2. If we do not want to read the entire file into memory, will have to take the buffer and “zhanglirovat” file, making operations seek-read-processing-seek-write. Thus, you can “move” the file pieces from place to place. Something like memcpy …

    bool MoveInFile (FILE * f, long from, long to, int size) {
     Char Buffer [256]; // Or specify the desired size other than 256, or make dynamic buffer
     if (size & gt; sizeof (buffer)) return false;
     fseek (f, from, 0);
     fread (buffer, 1, size); // We read a piece in the buffer
     fseek (f, to, 0);
     fwrite (buffer, 1, size); // Write prochitanogo piece to another position

The algorithm is complex – result in completely will not. All the more so at a considerably large pieces of the f-tion will have to greatly complicate – split one into several MoveInFile such that each piece would fit in the buffer. This is done in extreme cases.

But this is not all.

  1. It must be remembered that such operations are useful when the size of the file somewhere up to 10 … 100 MB, and then at a rate of above 1 MB will be problems. If small pieces – there may be problems with performance. It can also be a problem – where and how to get the right RAM Online. The x86 priodetsya take the memory in small chunks. When working with large files – you need to write chunks of not less than 4096 bytes, it is desirable to pieces is not less than the size of the cluster file system, and it is desirable to align the treatment of these boundaries. If before 4096 it was standard, I think soon move on to 8192 bytes. Therefore, when you work with files over 1 MB of frequently used classes / caching library.
  2. When you work with files over 4 GB will have to use seek64 or something like that.
  3. It is desirable to take into account littel-indian / big-indian otherwise you can catch the UB.
  4. Sometimes it is desirable to do fflush before closing, or if you are doing logging.

p.s. Your algorithm is not suitable for working with files soovsem. Because it is necessary to know in advance what kind will have the output file. Theoretically it is possible to calculate the position of the first and second removable piece, but, since you do not store files in memory – can be done by moving the algorithm 3 through MoveInFile. But it will be very difficult for you, but also highly impractical, because for the sake of one or two deletions will have to do a bit of overwriting files. This algorithm is advantageous to use only if soovsem not enough memory for the method of 1.2 and a 1MB file (on the eyes). I think you’d better better subtract everything, and do according to the algorithm 1.

Programmers, Start Your Engines!

Why spend time searching for the correct question and then entering your answer when you can find it in a second? That's what CompuTicket is all about! Here you'll find thousands of questions and answers from hundreds of computer languages.

Recent questions