C Primer Plus Chapter 4 (Strings and Formatted Input and Output)

Posted by turbocueca on Thu, 03 Feb 2022 18:38:19 +0100

1. Introduction to strings

Array of type 1.1 char and null character

  • C does not have a variable type dedicated to string storage, and strings are stored in arrays of type char
  • Arrays consist of contiguous storage units, where characters in strings are stored in adjacent storage units, one character per unit
abc\0
Each storage unit 1 byteEmpty Character
  • \0: null character, which C uses to mark the end of a string
  • The capacity of the array must be 1 more than the number of characters in the string to be stored
char c;
// Allocate 1 byte

char c[5];
// Allocate 5 bytes

1.2 Use string

  • C Prints strings using%s
#include <stdio.h>

int main() {
	char c[5] = "abc";

	printf("%s\n", c);
}

Strings and Characters

Character ('a')String ("a")
Basic type (char)Derived type (char array)
One character composition ('a')Two characters ('a'and \0)

1.3 strlen() function

  • strlen() function: gives the length of a character in a string
#include <stdio.h>
#include <string.h>
// Provides a prototype of the strlen() function

int main() {
	char c[5] = "abc";

	printf("length of %s is %zd\n", c, strlen(c));
	// length of abc is 3
}
  • The strlen() function knows where to stop and does not count empty characters

2. Constant and C Preprocessor

  • With symbolic constant, you only need to change the definition of the symbol constant, not look for places in the program where it is used, and then change it one by one

  • Create Symbol Constants

    • Declare a variable and assign it a value

      int i = 1;
      
      • Problem: The program may unintentionally change the value of a variable
    • C Preprocessor

      #define i 1
      
      • All is in the program are replaced with 1, a process known as compile-time substitution
      • All replacements in the program have been completed while running the program
      • Constants defined in this way are also known as manifest constant

2.1 const qualifier

  • C90 adds the const keyword, which limits a variable to read-only
  • Read-only: can calculate, print, cannot modify
const int i = 1;

2.2 Explicit Constants

  • limits.h: Provide details related to integer type size limits
manifest constantMeaning
CHAR_BITNumber of digits of type char
CHAR_MAXMaximum value of char type
CHAR_MINMinimum value of char type
  • You can replace the above CHAR with another constant name
manifest constantMeaning
CHARchar type
SCHARsigned char type
UCHARunsigned char type
SHRTshort type
USHRTunsigned char type
INTint type
UINTunsigned int type
LONGlong type
ULONGunsigned long type
LLONGlong long type
ULLONGUnsigned long type
  • float.h: Provide details related to floating point type size limits
manifest constantMeaning
FLT_MANT_DLGLast digit of float type
FLT_DIGMinimum number of significant digits of float type (decimal)
FLT_MIN_10_EXPMinimum negative exponent of float type with all significant numbers (base 10)
FLT_MAX_10_EXPMaximum positive exponent of float type (base 10)
FLT_MINMinimum positive float type with all precision preserved
FLT_MAXMaximum positive number of float type
FLT_EPSILONThe difference between 1.00 and the minimum float type value larger than 1.00
  • You can replace the above FLT with another constant name
manifest constantMeaning
FLTfloat type
DBLdouble type
LDBLlong double type

3. printf() and scanf()

  • I/O Functions

  • printf(): output function

  • scanf(): Input function

3.1 printf() function

Conversion Descriptionoutput
%aFloating point, hexadecimal, and p notation (C99/C11)
%AFloating point, hexadecimal, and p notation (C99/C11)
%cSingle Character
%dSigned decimal integer
%eFloating Point, e-notation
%EFloating Point, E-notation
%fFloating point, decimal notation
%gAutomatically select%f or%e depending on the value;% E format for exponential less than-4 or greater than or equal to precision
%GAutomatically select%f or%E depending on the value;% E format is used for exponential less than-4 or greater than or equal to precision
%iSigned decimal integer (same as%d)
%oUnsigned octal integer
%pPointer
%sCharacter string
%uUnsigned decimal integer
%xUnsigned hexadecimal integer, using hexadecimal number 0f
%XUnsigned hexadecimal integer, using hexadecimal number 0F
%%Print a percent sign

3.2 Use printf()

#include <stdio.h>
#define i 10

int main() {
	printf("%c %d %%\n", '$', 2 * i);
	// $ 20 %
}

3.3 Transform description modifier for printf()

ModifierMeaningExample
signsign"%-10d"
numberminimal field width reached
If the field cannot hold the number or string to be printed, a wider field will be used.
"%4d"
Numbersaccuracy
For%e,%E, and%f conversions, the number of digits to the right of the decimal point
For%g and%G conversions, the maximum number of significant digits
For the%s conversion, the maximum number of characters to be printed
For integer conversion, represents the minimum number of digits to be printed
"%5.2f" prints a floating point number
The field width is 5 characters, with 2 digits after the decimal point
hUsed with integer conversion instructions to represent values of type short int or unsigned short int"%hu","%hx","%6.4hd"
hhUsed with integer conversion instructions to represent values of type signed char or unsigned char"%hhu","%hhx","%6.4hhd"
jUsed with integer conversion instructions to represent intmax_t or uintmax_ Value of type T
These types are defined in stdint. In H
"%jd","%8jx"
lUsed with integer conversion instructions to represent values of type long int or unsigned long int"%ld","%8lu"
llUsed with integer conversion instructions to represent values of type long int or unsigned long int (C99)"%lld","%8llu"
LUsed with floating-point conversion instructions to represent values of type long double"%Lf","%10.4Le"
tUsed with integer conversion instructions to indicate ptrdiff_ Value of type T
ptrdiff_t is the type of two pointer differences (C99)
"%td","%12ti"
zUsed with integer conversion instructions to indicate size_ Value of type T
size_t is the type returned by sizeof
"%zd","%12zd"
signMeaningExample
-Left-align the item to be printed, that is, start printing the item from the left side of the field"%-20s"
+Signed value is positive, plus sign is displayed in front
Signed values, if negative, are preceded by a minus sign
"%+6.2f"
SpacesSigned values are positive, leading spaces are displayed in front (no symbols are displayed)
Signed values, if negative, are preceded by a minus sign
"% 6.2f"
#Convert the result to another form
If%o, start with 0
If%x or%X, start with 0x or 0X
For all floating-point formats, print a decimal character even if there are no numbers behind it
For%g and%G, prevent the 0 following the result from being deleted
"%#o","%#8.0f","%+#10.3e"
0For numeric values, fill the field width with leading 0 instead of spaces
For integer formats, if a -tag or precision is specified, the tag is ignored
"%010d","%08.3f"

Examples of using modifiers and Tags

#include <stdio.h>

int main() {
	int i = 123;

	printf("%d\n", i);
	// 123

	printf("%2d\n", i);
	// 123

	printf("%5d\n", i);
	//   123

	printf("%-5d\n", i);
	// 123
}
#include <stdio.h>

int main() {
	double d = 1.234;

	printf("%f\n", d);
	// 1.234000
	
	printf("%e\n", d);
	// 1.234000e+00
	
	printf("%4.2f\n", d);
	// 1.23
	
	printf("%3.1f\n", d);
	// 1.2

	printf("%10.3f\n", d);
	//      1.234

	printf("%10.3E\n", d);
	//  1.234E+00

	printf("%+4.2f\n", d);
	// +1.23
	
	printf("%010.2f\n", d);
	// 0000001.23
}

3.4 Significance of Transforming Explanations

3.4.1 conversion mismatch

#include <stdio.h>

int main() {
	int i = 336;
	int j = 65618;

	printf("short = %hd, unsigned short = %hu\n", i, i);
	// short = 336, unsigned short = 336

	printf("short = %hd, unsigned short = %hu\n", -i, -i);
	// short = -336, unsigned short = 65200

	printf("int = %d, char = %c\n", i, i);
	// int = 336, char = P
	// 336 = 256 + 80;80 = P

	printf("int = %d, short = %hd, char = %c\n", j, j, j);
	// int = 65618, short = 82, char = R
	// 65618 = 65536 + 82
	// 65618 = 256 * 256 + 82;82 = R

}

Parameter Transfer

#include <stdio.h>

int main() {
	float f = 1.0f;
	double d = 123456789.0;
	long l1 = 1, l2 = 1;

	printf("%ld %ld %ld %ld\n", f, d, l1, l2);
	// 0 1072693248 1409286144 1100836660
}
  • The first%ld gets the first four bytes of f
  • The second%ld gets the last four bytes of f
  • The third%ld gets the last four bytes of d
  • The fourth%ld gets the last four bytes of d

Return value of 3.4.2 printf()

  • The printf() function returns the number of printing characters

3.4.3 Print long strings

#include <stdio.h>

int main() {
	printf("abc ");
	printf("ABC\n");

	printf("abc \
ABC\n");

	printf("abc "
			"ABC\n");
}

3.5 Use scanf()

printf()scanf()
Parameter list: variables, constants, and expressionsA pointer to a variable
  • If scanf() is used to read the value of the basic variable type, add &before the variable name
  • If you use scanf() to read a string into a character array, do not use &
#include <stdio.h>

int main() {
	int i;
	float f;
	char c[10];

	printf("i, f = ");
	scanf("%d %f", &i, &f);

	printf("c[10] = ");
	scanf("%s", c);

	printf("%d %.2f %s\n", i, f, c);
}
Conversion DescriptionMeaning
%ccharacter
%dSigned decimal integer
%e,%f,%g,%aFloating Point (C99 Added%a)
%E,%F,%G,%AFloating Point (C99 Added%A)
%iSigned decimal integer
%oSigned octal integer
%pPointer (Address)
%sCharacter string
All characters from the first non-whitespace character to the next
%uUnsigned decimal integer
%x,%XSigned hexadecimal integer
ModifierMeaningExample
*Suppression assignment"%*d"
numberMaximum Field Width
The input reaches the maximum field width, or stops at the first encounter of a blank character
"%10s"
hhRead integers as signed char or unsigned char types"%hhd","%hhu"
llRead integers as long long or unsigned long type (C99)"%lld","%llu"
h, L or LRead integers as short, long types"%hd","%ld"
jUse intmax_t or uintmax_t type (C99)"%jd","%ju"
zReturn value type using sizeof (C99)"%zd","%zo"
tUse a type that represents the difference between two pointers (C99)"%td","%tx"

3.5.1 Viewing input (pit) from scanf()

  • scanf() retrieves data from buffer

  • scanf() feeds all input data into the buffer, fetches the data according to the input criteria in the buffer, and deletes the fetched data from the buffer

  • After the input is fetched, if there is data left, keep the data and get it from the buffer the next time scanf() is used, no more input is made

  • User input is not allowed when buffer is empty

  • scanf() automatically adds'\0'to the end of the character sequence when it feeds string type data into the execution array

#include <stdio.h>

int main() {
	int i;
	char c[10];

	scanf("%d %s", &i, c);
	// 1.23 abc

	printf("i = %d, c[10] = %s\n", i, c);
	// i = 1, c[10] = .23

	scanf("%s", c);
	
	printf("c[10] = %s\n", c);
	// c[10] = abc
}

Common characters in 3.5.2 format strings (memory principle unknown)

  • Users need to input strictly in the format string in scanf()
#include <stdio.h>

int main() {
	int i;
	char c[10];

	scanf("%d, %s", &i, c);
	// 1,abc

	printf("i = %d, c[10] = %s\n", i, c);
	// i = 1, c[10] = abc
}

Return value of 3.5.3 scanf()

  • The scanf() function returns the number of items successfully read

* modifiers for 3.6 printf() and scanf()

  • printf()
#include <stdio.h>

int main() {
	int i = 6;
	int j = 8;
	int a = 1234;
	double d = 242.5;

	printf("%*d\n", i, a);
	//   1234

	printf("%*.*f\n", j, i, d);
	// 242.500000
}
  • scanf()
#include <stdio.h>

int main() {
	int i = 0;

	scanf("%*d %*d %d", &i);
	// 1 2 3
	
	printf("%d\n", i);
	// 3
}

Usage tips for 3.7 printf()

  • Use a fixed field width large enough for neat and beautiful output
#include <stdio.h>

int main() {
	printf("%d %d %d\n", 1, 123, 12345);
	printf("%d %d %d\n", 12345, 123, 1);
	// 1 123 12345
	// 12345 123 1

	printf("%7d %7d %7d\n", 1, 123, 12345);
	printf("%7d %7d %7d\n", 12345, 123, 1);
	//       1     123   12345
	//   12345     123       1
}
  • Nesting numbers in text, specifying a field that is less than or equal to the width of the number
#include <stdio.h>

int main() {
	printf("ABC %10.2f abc\n", 1.234);
	// ABC       1.23 abc

	printf("ABC %.2f abc\n", 1.234);
	// ABC 1.23 abc
}

Topics: C