Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”

This article has participated in the “Digitalstar Project” and won a creative gift package to challenge the creative incentive money.

The printf() function is a standard print function in C. It is often used when debugging code or output information.

The conversion of printf function is described as follows:

Conversion specification modifier

The tag in printf()

Here is a practical example to illustrate the power of modifiers and tags.

For example, the voltage value of external equipment is collected through three sensors, and the collected data is printed out in real time through the serial port. Print relevant codes as follows:

        printf( "\r\n ch max min rms ave \r\n" );

        adc_all_value(0, &chAll_value);
        printf("%d %d %d %d %d\r\n".0, chAll_value.max, chAll_value.min, chAll_value.rms, chAll_value.ave);
        printf("%d %f %f %f %f\r\n".0, chAll_value.max * 3.3 / 4096, chAll_value.min * 3.3 / 4096, chAll_value.rms * 3.3 / 4096, chAll_value.ave * 3.3 / 4096);

        adc_all_value( 1, &ch1_value );
        printf( "%d %d %d %d %d\r\n".1, ch1_value.max, ch1_value.min, ch1_value.rms, ch1_value.ave );
        printf( "%d %f %f %f %f\r\n".1, ch1_value.max * 3.3 / 4096, ch1_value.min * 3.3 / 4096, ch1_value.rms * 3.3 / 4096, ch1_value.ave * 3.3 / 4096 );

        adc_all_value( 2, &ch2_value );
        printf( "%d %d %d %d %d\r\n".2, ch2_value.max, ch2_value.min, ch2_value.rms, ch2_value.ave );
        printf( "%d %f %f %f %f\r\n".2, ch2_value.max * 3.3 / 4096, ch2_value.min * 3.3 / 4096, ch2_value.rms * 3.3 / 4096, ch2_value.ave * 3.3 / 4096 );
        
Copy the code

The output through the serial port is as follows:

The maximum value, minimum value, effective value and average value of the sampling channel are displayed respectively. But the printed data format looks like a struggle. You want to be able to align the data with each column when printing. The first thing that comes to mind is to separate the data with Spaces. Change the code as follows:

        printf( "\r\n ch \t\tmax \t\t min \t\t rms \t\t ave \r\n" );

        adc_all_value(0, &chAll_value);
        printf("%d \t\t %d \t\t %d \t\t %d \t\t %d\r\n".0, chAll_value.max, chAll_value.min, chAll_value.rms, chAll_value.ave);
        printf("%d\t\t%f \t %f \t %f \t %f\r\n".0, chAll_value.max * 3.3 / 4096, chAll_value.min * 3.3 / 4096, chAll_value.rms * 3.3 / 4096, chAll_value.ave * 3.3 / 4096);

        adc_all_value( 1, &ch1_value );
        printf( "%d \t\t %d \t\t %d \t\t %d \t\t %d\r\n".1, ch1_value.max, ch1_value.min, ch1_value.rms, ch1_value.ave );
        printf( "%d\t\t%f \t %f \t %f \t %f\r\n".1, ch1_value.max * 3.3 / 4096, ch1_value.min * 3.3 / 4096, ch1_value.rms * 3.3 / 4096, ch1_value.ave * 3.3 / 4096 );

        adc_all_value( 2, &ch2_value );
        printf( "%d \t\t %d \t\t %d \t\t %d \t\t %d\r\n".2, ch2_value.max, ch2_value.min, ch2_value.rms, ch2_value.ave );
        printf( "%d\t\t%f \t %f \t %f \t %f\r\n".2, ch2_value.max * 3.3 / 4096, ch2_value.min * 3.3 / 4096, ch2_value.rms * 3.3 / 4096, ch2_value.ave * 3.3 / 4096 );
        
Copy the code

Add TAB characters between data so that output data is separated by Spaces.

This makes the printed data look neat, but when debugging the code, it takes several times to determine how many Spaces there are between two columns of data because each output is of different length, and the code looks messy. You can format the output data using the modifiers and tags of the printf function.

The code is modified as follows:

        char *s1="ch";
	char *s2="max";
	char *s3="min";
	char *s4="rms";
	char *s5="ave";
        
        printf( "\r\n%4s %12s %12s %12s %12s\r\n",s1,s2,s3,s4,s5 );

	adc_all_value(0, &chAll_value);
        printf("%4d %12d %12d %12d %12d\r\n".0, chAll_value.max, chAll_value.min, chAll_value.rms, chAll_value.ave);
        printf("%4d %12.6f %12.6f %12.6f %12.6f\r\n".0, chAll_value.max * 3.3 / 4096, chAll_value.min * 3.3 / 4096, chAll_value.rms * 3.3 / 4096, chAll_value.ave * 3.3 / 4096);

        adc_all_value( 1, &ch1_value );
        printf( "%4d %12d %12d %12d %12d\r\n".1, ch1_value.max, ch1_value.min, ch1_value.rms, ch1_value.ave );
        printf( "%4d %12.6f %12.6f %12.6f %12.6f\r\n".1, ch1_value.max * 3.3 / 4096, ch1_value.min * 3.3 / 4096, ch1_value.rms * 3.3 / 4096, ch1_value.ave * 3.3 / 4096 );

        adc_all_value( 2, &ch2_value );
        printf( "%4d %12d %12d %12d %12d\r\n".2, ch2_value.max, ch2_value.min, ch2_value.rms, ch2_value.ave );
        printf( "%4d %12.6f %12.6f %12.6f %12.6f\r\n".2, ch2_value.max * 3.3 / 4096, ch2_value.min * 3.3 / 4096, ch2_value.rms * 3.3 / 4096, ch2_value.ave * 3.3 / 4096 );
       
Copy the code

The data output is as follows:

At this point the data looks more clear and the data is sampled right – justified by default.

Numerical modifiers are used primarily here

Convert the name of each column to a string, and instead of printing the string directly, print it as a character, so that you can limit the length of characters in the output by numbers. For example, the string “ch” is set to four characters, so that output will be filled with Spaces if the character length is less than four characters. Then set all other characters to 12 bits, and any space left will be filled with Spaces, just as if it were printed.

For integer numbers, the number modifier also sets the number of digits to occupy, and if the number is insufficient, a space is used instead. For decimals, the number before the decimal point represents the total length of the decimal place, and the number after the decimal point represents the number of decimal places reserved. For example, “%12.6f” indicates that the floating point number is 12 bits in total and the decimal part is reserved for 6 bits. In other words, the whole part takes up 6 places, and the decimal part takes up 6 places.

All printed characters are right-aligned by default. If you want left-aligned characters, you simply add a “-” sign after the %. Here, change the printed data to left-aligned and keep two decimal places.

Modify the code as follows:

        char *s1="ch";
	char *s2="max";
	char *s3="min";
	char *s4="rms";
	char *s5="ave";
        
        printf( "\r\n%-4s %-12s %-12s %-12s %-12s\r\n",s1,s2,s3,s4,s5 );

		adc_all_value(0, &chAll_value);
        printf("%-4d %-12d %-12d %-12d %-12d\r\n".0, chAll_value.max, chAll_value.min, chAll_value.rms, chAll_value.ave);
        printf("%-4d %-12.2f %-12.2f %-12.2f %-12.2f %-12.2f\r\n".0, chAll_value.max * 3.3 / 4096, chAll_value.min * 3.3 / 4096, chAll_value.rms * 3.3 / 4096, chAll_value.ave * 3.3 / 4096);

        adc_all_value( 1, &ch1_value );
        printf( "%-4d %-12d %-12d %-12d %-12d\r\n".1, ch1_value.max, ch1_value.min, ch1_value.rms, ch1_value.ave );
        printf( "%-4d %-12.2f %-12.2f %-12.2f %-12.2f %-12.2f\r\n".1, ch1_value.max * 3.3 / 4096, ch1_value.min * 3.3 / 4096, ch1_value.rms * 3.3 / 4096, ch1_value.ave * 3.3 / 4096 );

        adc_all_value( 2, &ch2_value );
        printf( "%-4d %-12d %-12d %-12d %-12d\r\n".2, ch2_value.max, ch2_value.min, ch2_value.rms, ch2_value.ave );
        printf( "%-4d %-12.2f %-12.2f %-12.2f %-12.2f %-12.2f\r\n".2, ch2_value.max * 3.3 / 4096, ch2_value.min * 3.3 / 4096, ch2_value.rms * 3.3 / 4096, ch2_value.ave * 3.3 / 4096 );
       
Copy the code

The print result is as follows:

As you can see, the revised format looks much cleaner.

By using printf modifiers and tags, the program looks cleaner and the output is formatted better.