Fun little program in Linux---buffer interpretation + progress bar display detailed explanation (c language)

Table of contents

1. Explain what a buffer is:

2. Buffer effect

3. Four refresh strategies for the buffer:

4. Compare '\n' '\r'

5. Implementation of the progress bar

Let's take a look at the effect first:

CentOS 7 64-bit VMware 17

1. Explain what a buffer is:

A buffer is simply a portion of memory space. That is to say, a certain storage space is reserved in the memory space, and these storage spaces are used to buffer input or output data, and this part of the reserved space is called a buffer.

2. Buffer effect

Simple can be recorded as enabling low-speed input and output devices and high-speed CPU to work in harmony, avoiding low-speed input and output devices from occupying the CPU, freeing the CPU, enabling it to work efficiently and greatly speeding up the operation.

3. Four refresh strategies for the buffer:

a. Unbuffered

It can be understood as immediate execution without refreshing, and stderr is a typical representative of standard error conditions, which allows error information to be displayed immediately and directly.

b. Line buffering

The refresh operation will only be performed when a newline character (\n) is encountered in the input or output.

c. Full buffer

Only when the buffer is full will it be flushed. Typically represents the read and write of disk files.

d. The program will be automatically refreshed when it exits.

4. Compare '\n' '\r'

will continue to write down here
will continue to write down here

5. Implementation of the progress bar

First look at the code:

  1 #include <stdio.h>
  2 #include <string.h>
  3 #define max 101
  4 void test()
  5 {
  8     int i=0;
  9     const char* lable="|/-\\";
 10     char nums[max];
 11     memset(nums,'\0',sizeof(nums));
 12     while(i<=100)
 13     {
 14        printf("[%-100s][%-3d%%][%c]\r",nums,i,lable[i%4]);
 15         fflush(stdout);
 16         nums[i++]='#';
 17         usleep(30000);
 18 }
 19 printf("\n");
 20 }
 21 int main()
 22 {
 23    test();
 24     return 0;
 25 }


1. max is defined as 101 to reserve the character '\0', and the string output ends when '\0' is encountered.

2. const char* lable="|/-\\"; 

Use two backslashes, because of c language grammar problems, here is the simulation of the image of the cursor rotation, which can be understood from the comic strips I saw when I was a child.

3. memset(nums,'\0',sizeof(nums));

Here, the memset function is used to assign values ​​to the array, or it can be directly written as char nums[max]={"\0"}; the effect is the same.

4.  printf("[%-100s][%-3d%%][%c]\r",nums,i,lable[i%4]); 

%100s and %3d are formatting control characters, which are used to reserve the space size set by oneself. If no negative sign is added, it is right-aligned by default in c language, and the progress bar will go from right to left.

5. lable[i%4]

If you write i directly, as i increases, it will definitely cause an out-of-bounds access problem. Using i%4 can solve this problem very well.

6. The unit of usleep is microsecond (thousandth of a millisecond), and the unit of sleep is second

7.  fflush(stdout);

It is used to force a refresh and output directly to the display without buffering.

The following is a detailed introduction to fflush:

       fflush - flush a stream

       #include <stdio.h>

       int fflush(FILE *stream);

       For  output  streams,  fflush() forces a write of all user-space buffered data for the given output or update stream via the stream's underlying write function.  For input streams, fflush() discards
       any buffered data that has been fetched from the underlying file, but has not been consumed by the application.  The open status of the stream is unaffected.

       If the stream argument is NULL, fflush() flushes all open output streams.

       For a nonlocking counterpart, see unlocked_stdio(3).

       Upon successful completion 0 is returned.  Otherwise, EOF is returned and errno is set to indicate the error.

       EBADF  Stream is not an open stream, or is not open for writing.

       The function fflush() may also fail and set errno for any of the errors specified for write(2).

       For an explanation of the terms used in this section, see attributes(7).

       │Interface │ Attribute     │ Value   │
       │fflush()  │ Thread safety │ MT-Safe │
       C89, C99, POSIX.1-2001, POSIX.1-2008.

       The standards do not specify the behavior for input streams.  Most other implementations behave the same as Linux.

       Note that fflush() only flushes the user-space buffers provided by the C library.  To ensure that the data is physically stored on disk the kernel buffers must be  flushed  too,  for  example,  with
       sync(2) or fsync(2).

       fsync(2), sync(2), write(2), fclose(3), fopen(3), setbuf(3), unlocked_stdio(3)


Tags: C Linux Operation & Maintenance

Posted by FatStratCat on Sat, 28 Jan 2023 15:48:05 +0530