Chapter 14: More involved processing and I/O
The introduction connects the chapter’s text-processing and formatted-input topics to the pointer concepts covered earlier.
After this chapter you will be able to
- Pointers in text and input. Explain why pointers matter to the chapter’s treatment of text processing and formatted input.
- Number parsing and stopping. Trace how numberline_inner uses strtoull to collect numbers from a line and determine where parsing stops.
- Numberline input preparation. Explain what the numberline wrapper checks and prepares before relying on numberline_inner.
- Partial line detection. Describe how fgetline handles termination, newline removal, and a line that does not fit in one read.
- Bounded formatting with snprintf. Explain when to use snprintf and how its size argument and return value support bounded formatting or length calculation.
- Formatted input functions and arguments. Describe where fscanf, scanf, and sscanf read from, and explain why scanned values are passed through pointers.
- Whitespace and input line boundaries. Explain how a space in a scanf format matches whitespace and why scanning three numbers need not stop at the end of one line. State the section's practical advice for regular input patterns.
- Native locale for output. Explain why the example calls setlocale before outputting extended characters.
- Multibyte string character counts. Distinguish bytes in a multibyte string from the characters it represents, and explain the consequence for ordinary string functions.
- Wide character string conversion. Explain why the example converts a multibyte string to wide characters and describe the relevant behavior of mbsrtowcs.
- Portable UTF encoding choices. Explain why relying on an environment’s multibyte encoding can cause trouble when moving text between systems, and when explicitly choosing a UTF encoding is useful.
- UTF-16 surrogate pair tradeoffs. Explain why some Unicode characters occupy two UTF-16 words, how that differs from UCS-2, and why the section recommends UTF-8 or UTF-32 where possible.
- Restartable conversion state. Explain how restartable conversion functions use an mbstate_t state variable to continue processing when a multibyte input sequence is incomplete.
- Conversion output signals. Distinguish the return indications for incomplete input and for output produced over successive calls, including the special case of mb output.
- Binary versus text streams. Explain why text-mode I/O may change bytes and why streams used with fread or fwrite should be opened in binary mode.
- Binary I/O and file positions. Describe how fread and fwrite use and update a stream’s current file position, and how ftell and fseek let a program inspect or change that position.
- C23 binary file embedding. Describe what #embed inserts into C source and how the section uses it to initialize an array with a file’s binary contents.
What it builds on
- Pointer operations (chapter 11) · Basic pointer operations.
- String processing and conversion (chapter 8) · Earlier string processing and conversion functions.
- malloc and friends (chapter 13) · Dynamic allocation with malloc and realloc.
- Unformatted text input (chapter 8) · Earlier unformatted text input with fgets.
- Files and streams (chapter 8) · The distinction between stdin and other streams.
- Formatted output (chapter 8) · The printf family as a point of comparison.
- Strings are special (chapter 6) · The distinction between character arrays and terminated strings.
- Text I/O (chapter 8) · Earlier text I/O provides the context for outputting strings to a terminal.
Section by section
Introduction
The introduction connects the chapter’s text-processing and formatted-input topics to the pointer concepts covered earlier.
- Pointers in text and input: Explain why pointers matter to the chapter’s treatment of text processing and formatted input.
Why it matters: This connection explains why the chapter turns to these library features after covering pointers.
Key terms: pointers, text processing, formatted input
14.1 Text processing
The section uses a line-of-numbers program to explain string conversion, line reading, const safety, and safe formatting into character buffers.
- Number parsing and stopping: Trace how numberline_inner uses strtoull to collect numbers from a line and determine where parsing stops.
Why it matters: The end position lets the program advance through several numbers without splitting the line beforehand. - Numberline input preparation: Explain what the numberline wrapper checks and prepares before relying on numberline_inner.
Why it matters: These checks let the conversion routine operate on a terminated string and give the collected values appropriately sized storage. - String function const safety: Distinguish the const-safety limitations described for strtoull and older search interfaces from the alternatives noted in the section.
Why it matters: A returned pointer's type must not be mistaken for permission to modify read-only text. - Partial line detection: Describe how fgetline handles termination, newline removal, and a line that does not fit in one read.
Why it matters: The caller can distinguish a complete line from input that needs another read. - String formatting position: Explain how sprintnumbers uses sprintf's output and return value, and state the buffer assumption this makes.
Why it matters: Advancing by the returned length works only when the destination has room for the formatted text. - Bounded formatting with snprintf: Explain when to use snprintf and how its size argument and return value support bounded formatting or length calculation.
Why it matters: It permits formatting when the result length is uncertain without overflowing the destination.
Key terms: numberline_inner, strtoull, next, base, numberline, np, memchr, malloc, realloc, const-safe
14.2 Formatted input
This section introduces the scanf family for formatted input and explains conventions that make it easy to read more input than intended.
- Formatted input functions and arguments: Describe where fscanf, scanf, and sscanf read from, and explain why scanned values are passed through pointers.
Why it matters: Choosing the right function and argument type is the starting point for using formatted input correctly. - Whitespace and input line boundaries: Explain how a space in a scanf format matches whitespace and why scanning three numbers need not stop at the end of one line. State the section's practical advice for regular input patterns.
Why it matters: An apparent line-based format may consume input across line boundaries. - Character and string scanning: Distinguish what %c and %s scan, and describe the section's character-class example for scanning and discarding a line ending.
Why it matters: These formats can consume and terminate text differently even though they take the same pointer type. - Floating point format differences: Explain the section's warning that scanf and printf differ in floating-point format conventions, and state its suggested double and long double forms.
Why it matters: Assuming input and output format conventions are identical can lead to the wrong format for a floating-point type.
Key terms: fscanf, scanf, sscanf, stdin, pointers, white space, scanf family, %c, %s, char*
14.3 Extended character sets
This section explains how C programs can use extended characters through locales, multibyte strings, Unicode code points, and conversion to wide characters.
- Native locale for output: Explain why the example calls setlocale before outputting extended characters.
Why it matters: The locale call is a practical prerequisite for the section’s extended-text output example. - Multibyte string character counts: Distinguish bytes in a multibyte string from the characters it represents, and explain the consequence for ordinary string functions.
Why it matters: It explains why a string can be copied normally but needs different handling when characters must be counted. - Unicode code points and escapes: Describe Unicode code points as character concepts and explain how the section writes one in a C string literal.
Why it matters: Code points and escapes give the example a way to name characters that may not be on the keyboard. - Wide character string conversion: Explain why the example converts a multibyte string to wide characters and describe the relevant behavior of mbsrtowcs.
Why it matters: Conversion supplies the character-aware size used by mbsrlen and the allocated wide-string example. - Individual multibyte character parsing: Describe how the example uses mbrtowc for finer-grained parsing and handles an incomplete character.
Why it matters: This lets the example locate individual characters when processing a multibyte string.
Key terms: setlocale, native locale, extended characters, multibyte character, multibyte string, null terminated, strlen, mbsrlen, Unicode, code point
14.4 UTF character encodings
The section explains C’s direct support for UTF encodings, why UTF-16 needs special care, and where standard-library and compiler support may vary.
- Portable UTF encoding choices: Explain why relying on an environment’s multibyte encoding can cause trouble when moving text between systems, and when explicitly choosing a UTF encoding is useful.
Why it matters: An explicit encoding helps when text must work across environments that may use different defaults. - UTF literal prefixes and types: Describe how C spells UTF-8, UTF-16, and UTF-32 string literals and the corresponding character types stated in the section.
Why it matters: These prefixes let source code specify which UTF encoding a literal uses. - UTF-16 surrogate pair tradeoffs: Explain why some Unicode characters occupy two UTF-16 words, how that differs from UCS-2, and why the section recommends UTF-8 or UTF-32 where possible.
Why it matters: Counting UTF-16 words as characters can be misleading, and the encoding choice affects what a single word can represent. - UTF library and standard limits: State what the c8, c16, and c32 function names indicate, why those functions may not suffice on every platform, and what C23 guarantees for char16_t and char32_t.
Why it matters: Code that depends on particular UTF facilities or guarantees must account for the C version and platform.
Key terms: multibyte encoding, UTF-8, UTF-16, UTF-32, u8, u, char8_t, char16_t, char32_t, surrogate pairs
14.5 Restartable text conversion
This section explains how restartable conversion functions preserve state across incomplete multibyte input and illustrates their use in a UTF-8 scanning example.
- Restartable conversion state: Explain how restartable conversion functions use an mbstate_t state variable to continue processing when a multibyte input sequence is incomplete.
Why it matters: Saved conversion state lets a program handle a character split across input reads. - Conversion output signals: Distinguish the return indications for incomplete input and for output produced over successive calls, including the special case of mb output.
Why it matters: These indications tell a caller whether to supply more input or keep collecting output. - Stateful input scanning example: Trace why the example sets the locale, reuses one conversion state across calls to mbrtoc8, and can process input split across a fixed-size buffer.
Why it matters: The example shows how persistent conversion state handles real input that does not align with character or line boundaries.
Key terms: restartable, state parameter, mbstate_t, multibyte mb encoding, mbincomplete, mbstored, mb encoding, setlocale, mbrtoc8, input buffer ib
14.6 Binary streams
Explains why binary streams are needed for byte-preserving I/O, how to read and position within them, their portability limits, and how C23 can embed binary files in source code.
- Binary versus text streams: Explain why text-mode I/O may change bytes and why streams used with fread or fwrite should be opened in binary mode.
Why it matters: Binary mode prevents text translations from altering data that must retain its exact bytes. - Binary I/O and file positions: Describe how fread and fwrite use and update a stream’s current file position, and how ftell and fseek let a program inspect or change that position.
Why it matters: Together, these functions let a program revisit and access particular bytes in a file. - Raw representation portability: Explain why writing an object’s internal representation to a binary file does not make that file portable across platforms or executions.
Why it matters: Preserving bytes is not the same as ensuring another program will interpret them the same way. - Large file offset limit: State why ftell and fseek are unsuitable for very large file offsets in the interface described here.
Why it matters: File-position operations have a size limit worth checking before applying them to large files. - C23 binary file embedding: Describe what #embed inserts into C source and how the section uses it to initialize an array with a file’s binary contents.
Why it matters: Embedding makes a fixed binary asset available to the program without reading that asset at runtime.
Key terms: text mode, binary mode, fread, fwrite, ftell, fseek, file position, SEEK_SET, internal representations, endian-ness
14.7 Summary
Where this is used later
- Error checking and cleanup (chapter 15) · The earlier series of number-printing functions.
- Type-generic C library functions (chapter 18) · Examines the type-generic C library interfaces mentioned here.
Concepts explained in this chapter
- code pointA code point is a numeric value identifying a character or abstract symbol in a character repertoire such as Unicode.
- multibyte stringA multibyte string is a character sequence in which one logical character may occupy multiple bytes according to the active C locale encoding.
- mbstate_tmbstate_t is the C standard-library type that represents the conversion state required by restartable multibyte character functions.
- setlocalesetlocale is a C standard-library function that selects or queries the program's current locale for locale-sensitive behavior.
- UnicodeUnicode is a universal character encoding standard that assigns code points and properties to characters and symbols across writing systems.
- extended character setAn extended character set is a repertoire that includes characters beyond the limited C basic character set, such as characters from additional scripts and writing systems.
- wide characterA wide character is a value of type wchar_t that represents exactly one character from an extended character set.
- escape sequenceAn escape sequence is source-code notation beginning with a backslash that encodes a character or special value.
- localeA locale is a set of language- and culture-dependent conventions governing the interpretation and presentation of textual and numeric data.
- mbrtowcmbrtowc is a C standard-library conversion function that converts a multibyte character sequence to a wide character while maintaining restartable conversion state.
- mbsrtowcsmbsrtowcs is a C standard-library function that converts a multibyte string to a wide character string while maintaining conversion state.
- multibyte characterA multibyte character is a sequence of bytes interpreted as one character from an extended character set.
- wide character stringA wide character string is a null-terminated array of wchar_t values representing characters from an extended character set.
- sprintfsprintf is a C standard-library function that formats converted values into a character array without imposing a destination-size limit.
- strtoullstrtoull is a C standard-library function that converts the initial part of a string to an unsigned long long integer using a specified or inferred base.
- #embed#embed is a C23 preprocessing directive that inserts the binary contents of a file into a translation unit as a sequence of integer values.
- freadfread is a C standard-library function that reads a specified number of objects from a stream into memory.
- fwritefwrite is a C standard-library function that writes a specified number of objects from memory to a stream.
- byte streamA binary stream is a C stream that transfers data as sequences of bytes without text-oriented character transformations.
- UTF-8UTF-8 is a variable-length Unicode encoding that represents each code point as a sequence of one to four bytes.
- __has_embed__has_embed is a C23 preprocessing feature that tests whether a specified file can be embedded.
- endiannessEndianness is the ordering convention used to encode the bytes of multi-byte values in a representation.
- file positionA file position is the location within a stream at which the next read or write occurs.
- fseekfseek is a C standard-library function that changes a stream's file position relative to a specified reference position.
- ftellftell is a C standard-library function that reports a stream's current file position as a byte offset from the beginning of the file.
- format stringA format string is a character sequence containing literal text and format specifiers that controls formatted output conversion.
- const qualifierA const-qualified type is a C type whose referenced value is not modifiable through an expression having that type.
- character literalA character literal is a C source-code literal enclosed in single quotes that represents an integer character code.
- character classA character class is a set of characters sharing a property such as being alphabetic, numeric, whitespace, or punctuation.
- exceptionAn exception is an abnormal execution condition that can interrupt ordinary computation and potentially terminate a program.
These guides are generated from the text of Manning books by Manning's knowledge graph and link to the sections they draw on. The full books are available on liveBook and at manning.com.
