Characters and Strings
CEN116 Algorithms and Programming II
Fundamentals of Strings and Characters
• Every program is composed of characters that—when grouped
together meaningfully—the computer interprets as a series of
instructions used to accomplish a task
• A program may contain character constants—each is an int value
represented as a character in single quotes
• A character constant’s value is that character’s integer value in the
machine’s character set
Fundamentals of Strings and Characters
• A string is a series of characters treated as a single unit
• may include letters, digits and various special characters such as +, -, *, / and
$
• String literals, or string constants, are written in double quotation
marks
• Strings Are Null Terminated
• Every string must end with the null character ('\0')
Fundamentals of Strings and Characters
Strings and Pointers
• You access a string via a pointer to its first character
• A string’s “value” is the address of its first character
• In C, it’s appropriate to say that a string is a pointer to the string’s first
character
• This is just like arrays, because strings are simply arrays of characters
Fundamentals of Strings and Characters
Initializing char Arrays and char * Pointers
• You can initialize a character array or a char * variable with a string
• char color[] = "blue";
• const char *colorPtr = "blue";
• The first definition creates a 5-element array color containing
modifiable
• The second definition creates the pointer variable colorPtr that
points to the letter 'b' in "blue", which is not modifiable
Fundamentals of Strings and Characters
• The color array definition also can be written as
• char color[] = {'b', 'l', 'u', 'e', ‘\0'};
• When storing a string in a char array, the array must be large enough
to store the string and its terminating null character
• C allows you to store strings of any length
• If a string is longer than the char array in which you store it,
characters beyond the array’s end may overwrite other data in
memory
Fundamentals of Strings and Characters
Reading a String with scanf
• Assume a char array word containing 20 elements
• scanf("%19s", word);
• Since word is an array, its name is a pointer to the first element
• The field width 19 in the preceding statement ensures scanf
reads a maximum of 19 characters, saving the last array element
for the string’s terminating null character
• Prevents scanf from writing characters into memory beyond the
array’s last element
• Always use a field width when reading strings with scanf
Character-Handling Library
• The character-handling library (<ctype.h>) contains functions that
test and manipulate character data
• Each function receives an unsigned char (represented as an int)
or EOF as an argument
• Characters are often manipulated as integers because a character in C
is a one-byte integer
• EOF’s value is typically -1
• The following table summarizes the character-handling library
functions
Prototype Function description
int isblank(int c); Returns a true value if c is a blank character that separates words in a line of text;
otherwise, it returns 0 (false).
int isdigit(int c); Returns a true value if c is a digit; otherwise, it returns 0 (false).
int isalpha(int c); Returns a true value if c is a letter; otherwise, it returns 0 (false).
int isalnum(int c); Returns a true value if c is a digit or a letter; otherwise, it returns 0 (false).
int isxdigit(int c); Returns a true value if c is a hexadecimal digit character; otherwise, it returns 0
(false). (See online Appendix E for a detailed explanation of binary numbers, octal
numbers, decimal numbers and hexadecimal numbers.)
int islower(int c); Returns a true value if c is a lowercase letter; otherwise, it returns 0 (false).
int isupper(int c); Returns a true value if c is an uppercase letter; otherwise, it returns 0 (false).
int tolower(int c); If c is an uppercase letter, tolower returns c as a lowercase letter; otherwise, it
returns the argument unchanged.
Prototype Function description
int toupper(int c); If c is a lowercase letter, toupper returns c as an uppercase letter; otherwise, it
returns the argument unchanged.
int isspace(int c); Returns a true value if c is a whitespace character—newline ('\n'), space, form
feed ('\f'), carriage return ('\r'), horizontal tab ('\t') or vertical tab
('\v')—otherwise, it returns 0 (false).
int iscntrl(int c); Returns a true value if c is a control character—horizontal tab ('\t'), vertical tab
('\v'), form feed ('\f'), alert ('\a'), backspace ('\b'), carriage return
('\r'), newline ('\n') and others—otherwise, it returns 0 (false).
int ispunct(int c); Returns a true value if c is a printing character other than a space, a digit, or a
letter—such as $, #, (, ), [, ], {, }, ;, : or %—otherwise, it returns 0 (false).
int isprint(int c); Returns a true value if c is a printing character (i.e., a character that’s visible on
the screen) including a space; otherwise, it returns 0 (false).
int isgraph(int c); Returns a true value if c is a printing character other than a space; otherwise, it
returns 0 (false).
Functions isdigit, isalpha, isalnum
and isxdigit
• isdigit determines whether its argument is a digit (0–9)
• isalpha determines whether its argument is an uppercase (A–Z) or
lowercase letter (a–z)
• isalnum determines whether its argument is an uppercase letter, a
lowercase letter or a digit
• isxdigit determines whether its argument is a hexadecimal digit
(A–F, a–f, 0–9).
Functions islower, isupper, tolower
and toupper
• islower determines whether its argument is a lowercase letter (a–
z).
• isupper determines whether its argument is an uppercase letter
(A–Z).
• tolower converts an uppercase letter to a lowercase letter and
returns the lowercase letter. If the argument is not an uppercase
letter, tolower returns the argument unchanged.
• toupper converts a lowercase letter to an uppercase letter and
returns the uppercase letter. If the argument is not a lowercase letter,
toupper returns the argument unchanged.
Functions isspace, iscntrl, ispunct,
isprint and isgraph
• isspace determines whether a character is a whitespace character—
newline ('\n'), space, form feed ('\f'), carriage return ('\r'), horizontal
tab ('\t') or vertical tab ('\v')—otherwise, it returns 0 (false).
• iscntrl determines whether a character is a control character—horizontal
tab ('\t'), vertical tab ('\v'), form feed ('\f'), alert ('\a'), backspace
('\b'), carriage return ('\r'), newline ('\n') and others
• ispunct determines whether a character is a printing character other than
a space, a digit or a letter, such as $, #, (, ), [, ], {, }, ;, : or %
• isprint determines whether a character can be displayed on the screen
(including the space character).
• isgraph is the same as isprint, but the space character is not included
Standard Input/Output Library Functions
• This section presents the standard input/output (<stdio.h>) library’s
character- and string-manipulation functions, which we summarize in
the following table.
Standard Input/Output Library Functions
Function prototype Function description
int getchar(void); Returns the next character from the standard input as an
integer.
char *fgets(char *s, Reads characters from the specified stream into the array
int n, FILE *stream); s until a newline or end-of-file character is encountered,
or until n-1 bytes are read. This chapter uses the stream
stdin—the standard input stream—to read characters
from the keyboard. A terminating null character is
appended to the array. Returns the string that was read
into s. If a newline is encountered, it’s included in the
stored string.
int putchar(int c); Prints the character stored in c and returns it as an
integer.
Standard Input/Output Library Functions
Function prototype Function description
int puts(const char Prints the string s followed by a newline character. Returns a
*s); nonzero integer if successful, or EOF if an error occurs.
int sprintf(char *s, Equivalent to printf, but the output is stored in the array s
const char instead of printed on the screen. Returns the number of
*format, ...); characters written to s, or EOF if an error occurs.
int sscanf(char *s, Equivalent to scanf, but the input is read from the array s
const char rather than from the keyboard. Returns the number of items
*format, ...); successfully read by the function, or EOF if an error occurs.
Functions fgets and putchar
• Next example uses functions fgets and putchar to read a line of text from
the standard input (keyboard) and recursively output the line’s characters in
reverse order
• Line 11 uses fgets to read characters into its char array argument until it
encounters a newline or the end-of-file indicator, or until the maximum
number of characters is read
• The maximum number of characters is one fewer than fgets’s second
argument
• The third argument is the stream from which to read characters (stdin)
• When reading terminates, fgets appends a null character to the array
• Function putchar (line 27) prints its character argument
Functions fgets and putchar
1. #include <stdio.h>
2. #define SIZE 80
3.
4.
5. void reverse(const char * const sPtr);
6.
7. int main(void) {
8. char sentence[SIZE] = "";
9.
10. puts("Enter a line of text:");
11. fgets(sentence, SIZE, stdin); // read a line of text
12.
13. printf("\n%s", "The line printed backward is:");
14. reverse(sentence);
15. puts("");
16.}
17.
Functions fgets and putchar
18.
19.// recursively outputs characters in string in reverse order
20.void reverse(const char * const sPtr) {
21. // if end of the string
22. if ('\0' == sPtr[0]) { // base case
23. return;
24. }
25. else { // if not end of the string
26. reverse(&sPtr[1]); // recursion step
27. putchar(sPtr[0]); // use putchar to display character
28. }
29.}
Functions fgets and putchar
Enter a line of text:
Characters and Strings
The line printed backward is:
sgnirtS dna sretcarahC
Functions fgets and putchar
Function reverse
• reverse prints a line of text backward
• If the array’s first character is the null character, reverse returns.
• Otherwise, reverse calls itself recursively with the subarray’s address beginning at
element sPtr[1]
• Line 27 outputs sPtr[0] when the recursive call completes
• The order lines 26 and 27 causes reverse to walk to the string’s terminating null
character before displaying any characters
• As the recursive calls complete, the characters are output in reverse order.
Function getchar
• Next example uses functions getchar to read one character at a
time from the standard input into the character array sentence,
then uses puts to display the characters as a string
• getchar reads a character from the standard input and returns the
character as an integer
• The program stops inputting characters when 79 characters have
been read or when getchar reads a newline character
• Line 17 appends a null character to sentence to terminate the string
Function getchar
1. #include <stdio.h>
2. #define SIZE 80
3. int main(void) {
4. int c = 0; // variable to hold character input by user
5. char sentence[SIZE] = "";
6. int i = 0;
7. puts("Enter a line of text:");
13.// use getchar to read each character
14. while ((i < SIZE - 1) && (c = getchar()) != '\n') {
15. sentence[i++] = c;
16. }
17. sentence[i] = '\0'; // terminate string
18. puts("\nThe line entered was:");
19. puts(sentence); // display sentence
20.}
Function sprintf
• Next example uses function sprintf to print formatted data into
char array s
• Uses the same conversion specifications as printf
Function sprintf
1. #include <stdio.h>
2. #define SIZE 80
3.
4. int main(void) {
5. int x = 0;
6. double y = 0.0;
7.
8. puts("Enter an integer and a double:");
9. scanf("%d%lf", &x, &y);
10.
11. char s[SIZE] = ""; // create char array
12. sprintf(s, "integer:%6d\ndouble:%7.2f", x, y);
13.
14. printf("The formatted output stored in array s
is:\n%s\n", s);
15.}
Function sprintf
Enter an integer and a double:
298 87.375
The formatted output stored in array s is:
integer: 298
double: 87.38
Function sscanf
• Next example demonstrates function sscanf, which reads
formatted data from a string
Function sscanf
1. #include <stdio.h>
2.
3. int main(void) {
4. char s[] = "31298 87.375";
5. int x = 0;
6. double y = 0;
7.
8. sscanf(s, "%d%lf", &x, &y);
9. puts("The values stored in character array s
are:");
10. printf("integer:%6d\ndouble:%8.3f\n", x, y);
11.}
Function sscanf
OUTPUT:
The values stored in character array s are:
integer: 31298
double: 87.375
String-Manipulation Functions of the String-
Handling Library
• The string-handling library (<string.h>) provides functions for:
• manipulating string data (copying strings and concatenating strings),
• comparing strings,
• searching strings for characters and other strings,
• tokenizing strings (separating strings into logical pieces), and
• determining the length of strings.
• Summarized in the following table
• Other than strncpy, each function appends the null character to its result.
String-Manipulation Functions of the String-
Handling Library
Function prototype Function description
char *strcpy(char *s1, const char *s2) Copies string s2 into array s1 and returns s1.
char *strncpy(char *s1, const char *s2, Copies at most n characters of string s2 into array s1
size_t n) and returns s1.
char *strcat(char *s1, const char *s2) Appends string s2 to array s1 and returns s1. String
s2’s first character overwrites s1’s terminating null
character.
char *strncat(char *s1, const char *s2, Appends at most n characters of string s2 to array s1
size_t n) and returns s1. String s2’s first character overwrites
s1’s terminating null character.
String-Manipulation Functions of the String-
Handling Library
• Functions strncpy and strncat specify a size_t parameter
• Function strcpy copies the string in the second argument into the char array
in its first argument.
• You must ensure that the array is large enough to store the string and its
terminating null character, which is also copied.
• Function strncpy is equivalent to strcpy but copies only the specified
number of characters.
• Function strncpy will not copy the terminating null character of its second
argument unless the number of characters to be copied is more than the
length.
• Logic error if you do not append a terminating null character to strncpy’s
first argument when the third argument is less than or equal to the second
string’s length
Functions strcpy and strncpy
• Next example
• uses strcpy to copy the string in array x into array y
• uses strncpy to copy the first 14 characters of array x into array z
• Line 18 appends a null character to z because strncpy does not write a
terminating null character
• the third argument is less than the second argument’s string length
Functions strcpy and strncpy
1. #include <stdio.h>
2. #include <string.h>
3. #define SIZE1 25
4. #define SIZE2 15
5. int main(void) {
6. char x[] = "Happy Birthday to You"; // initialize char array x
7. char y[SIZE1] = ""; // create char array y
8. char z[SIZE2] = ""; // create char array z
13. // copy contents of x into y
14. printf("%s%s\n%s%s\n",
15. "The string in array x is: ", x,
16. "The string in array y is: ", strcpy(y, x));
17. strncpy(z, x, SIZE2 - 1); // copy first 14 characters of x into z
18. z[SIZE2 - 1] = '\0'; // terminate string in z, because '\0' not
copied
19. printf("The string in array z is: %s\n", z);
20.}
Functions strcpy and strncpy
The string in array x is: Happy Birthday to You
The string in array y is: Happy Birthday to You
The string in array z is: Happy Birthday
Functions strcat and strncat
• Function strcat appends its second argument string to the string in
its char array first argument, replacing the first argument’s null
character
• Ensure that the array used to store the first string is large enough to store
the first string, the second string and the terminating null character copied
from the second string
• Function strncat appends a specified number of characters from
the second string to the first string and adds a terminating null
character
• Next example demonstrates strcat and strncat
Functions strcat and strncat
1. #include <stdio.h>
2. #include <string.h>
3.
4. int main(void) {
5. char s1[20] = "Happy "; // initialize char array s1
6. char s2[] = "New Year "; // initialize char array s2
7. char s3[40] = ""; // initialize char array s3 to empty
8.
9. printf("s1 = %s\ns2 = %s\n", s1, s2);
13. // concatenate s2 to s1
14. printf("strcat(s1, s2) = %s\n", strcat(s1, s2));
15.
16. // concatenate first 6 characters of s1 to s3
17. printf("strncat(s3, s1, 6) = %s\n", strncat(s3, s1, 6));
18.
19. // concatenate s1 to s3
20. printf("strcat(s3, s1) = %s\n", strcat(s3, s1));
21.}
Functions strcat and strncat
s1 = Happy
s2 = New Year
strcat(s1, s2) = Happy New Year
strncat(s3, s1, 6) = Happy
strcat(s3, s1) = Happy Happy New Year
Comparison Functions of the String-Handling
Library
Function prototype Function description
int strcmp(const char *s1, Compares the string s1 with the string s2. The function
const char *s2); returns 0, less than 0 or greater than 0 if s1 is equal to, less
than or greater than s2, respectively.
int strncmp(const char *s1, Compares up to n characters of the string s1 with the
const char *s2, size_t n); string s2. The function returns 0, less than 0 or greater
than 0 if s1 is equal to, less than or greater than s2,
respectively.
Comparison Functions of the String-Handling
Library
• Next example compares three strings using strcmp and strncmp
• Function strncmp is equivalent to strcmp but compares up to a
specified number of characters
• Function strncmp does not compare characters following a null character in
a string
• The program prints the integer value returned by each function call
Comparison Functions of the String-Handling
Library
1. #include <stdio.h>
2. #include <string.h>
3.
4. int main(void) {
5. const char *s1 = "Happy New Year";
6. const char *s2 = "Happy New Year";
7. const char *s3 = "Happy Holidays";
11. printf("s1 = %s\ns2 = %s\ns3 = %s\n\n%s%2d\n%s%2d\n%s%2d\n\n",
12. s1, s2, s3,
13. "strcmp(s1, s2) = ", strcmp(s1, s2),
14. "strcmp(s1, s3) = ", strcmp(s1, s3),
15. "strcmp(s3, s1) = ", strcmp(s3, s1));
16.
17. printf("%s%2d\n%s%2d\n%s%2d\n",
18. "strncmp(s1, s3, 6) = ", strncmp(s1, s3, 6),
19. "strncmp(s1, s3, 7) = ", strncmp(s1, s3, 7),
20. "strncmp(s3, s1, 7) = ", strncmp(s3, s1, 7));
21.}
Comparison Functions of the String-Handling
Library
s1 = Happy New Year
s2 = Happy New Year
s3 = Happy Holidays
strcmp(s1, s2) = 0
strcmp(s1, s3) = 1
strcmp(s3, s1) = -1
strncmp(s1, s3, 6) = 0
strncmp(s1, s3, 7) = 1
strncmp(s3, s1, 7) = -1
Comparison Functions of the String-Handling
Library
How Strings Are Compared
• The alphabet is more than just 26 letters—it’s an ordered list of characters
• Each letter occurs in a specific position—“Z” is the alphabet’s 26th letter
• All characters are represented as numeric codes in character sets such as ASCII
and Unicode
• Lowercase letters have higher numeric values than uppercase letters, so “a” is
greater than “A.”
• The computer compares strings by their characters’ numeric codes
• Called a lexicographical comparison
• The negative and positive values returned by strcmp and strncmp are
implementation-dependent
Function strlen
• Function strlen takes a string as an argument and returns the
number of characters in the string—the terminating null character is
not included in the length.
Function strlen
1. #include <stdio.h>
2. #include <string.h>
3.
4. int main(void) {
5. const char *string1 = "abcdefghijklmnopqrstuvwxyz";
6. const char *string2 = "four";
7. const char *string3 = "Boston";
8.
9. printf("%s\"%s\"%s%zu\n%s\"%s\"%s%zu\n%s\"%s\"%s%zu\n",
10. "The length of ", string1, " is ", strlen(string1),
11. "The length of ", string2, " is ", strlen(string2),
12. "The length of ", string3, " is ", strlen(string3));
13.}
Function strlen
The length of "abcdefghijklmnopqrstuvwxyz" is 26
The length of "four" is 4
The length of "Boston" is 6
References
• C How to Program, Ninth Edition by Deitel & Deitel, Pearson, 2022.