Strings
COP-3223H
Table of Contents
Strings
Recall the "hello, world!\n" program:
printf("hello, world!\n");
Strings are character arrays
char str[] = "hello, world!\n";
printf("%s", str); // %s is for strings (character arrays)
#include <stdio.h>
int main(int argc, char **argv) {
/* printf("hello, world!\n"); */
char str[] = "hello, world!\n";
char nullchar = '\0';
/* printf("%s", str); */
int len = 0;
printf("print using a for loop\n");
/* for (int i = 0; i < 14; i++) { */
/* putchar(str[i]); */
/* } */
char c;
int i = 0;
while ( (c = str[i++]) != '\0') {
putchar(c);
}
}
#include <stdio.h>
int main(int argc, char **argv) {
printf("hello, world!\n");
char str[] = "hello, world!\n";
printf("%s", str);
str[7] = 'p';
str[8] = 'a';
str[9] = 'u';
str[10] = 'l';
str[11] = '!';
printf("%s", str);
}
Recall: the character type
- Characters represent single digits, letters, punctuation, etc.
- Wrapped with single quotes:
'
Recall that there are also non-printable characters like '\n';
Strings are null-delimited
Diagram
- Memory slots of string character array
- Null character ends the string
'\0'.
By convention, strings do not have fixed sizes, but end with a special character, null '\0'
Why Pascal Is Not My Favorite Programming Language : Brian W. Kernighan : Fre…
Character arrays
char chararray[] = { 'h', 'e', 'l', 'l', 'o', '!', '\n', '\0' };
printf("%s", chararray);
Just like integer arrays, we can make a character array.
char chararraydelim[] = { 'h', 'e', 'l', 'l', 'o', '!', '\n', '\0', 'X', '\n' };
printf("%s", chararraydelim);
char chararraynodelim[] = { 'h', 'e', 'l', 'l', 'o', '!', '\n', 'X', '\n' };
printf("%s", chararraynodelim);
#include <stdio.h>
int main(int argc, char **argv) {
/* char str[] = "hello, world!\n"; */
/* printf("%s\n", str); */
/* str[7] = 'p'; */
/* str[8] = 'a'; */
/* str[9] = 'u'; */
/* str[10] = 'l'; */
/* str[11] = '!'; */
/* printf("%s", str); */
char chararray[] = { 'h', 'e', 'l', 'l', 'o', '!', '\n', '\0' };
printf("FIRST: %s", chararray);
char chararraydelim[] = { 'e', 'e', 'l', 'l', 'o', '!', '\n', '\0', 'X', '\n' };
printf("SECOND: %s", chararraydelim);
char chararraynodelim[] = { 'h', 'e', 'l', 'l', 'o', '!', '\n', 'X', '\n' };
printf("THIRD: %s", chararraynodelim);
}
String literals
- Like integer (
1,43, etc.), float, or characters - Wrap with double quotes:
"
char chararray = "hello!\n";
This array has the same contents as the previous array
Example: counting characters in a string
Write a program that, given a string str, counts how often a character c appears in string.
String operations
#include <string.h>
Getting length
With a loop
int i = 0;
while ('\0' != s[i]) {
i++;
}
int i = 0;
while ('\0' != s[i++]);
Function
strlen
Compare strings
#include <stdio.h>
int main(int argc, char **argv) {
char str1[] = "hello!\n";
char str2[8] = { 'h', 'e', 'l', 'l', 'o', '!', '\n', '\0' };
printf("%s", str1);
printf("%s", str2);
printf("str1 == str2?\n");
if (str1 == str2) {
printf("yes!\n");
} else {
printf("no!\n");
}
printf("str1[0] == str2[0]?\n");
if (str1[0] == str2[0]) {
printf("yes!\n");
} else {
printf("no!\n");
}
}
str1 and str2 are the addresses of the beginning of the string, not the actual characters.
str1 and str2 are pointing to different memory slots, so these are not the same.
Example: compare strings by hand
Safe(r) usage
| Operation | Function |
|---|---|
strncmp |
Compare two strings |
fgets |
Read a string |
strlcpy |
Copy a string |
Comparing strings
strncmp
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv) {
char str1[] = "hello!\n";
char str2[8] = { 'h', 'e', 'l', 'l', 'o', '!', '\n', '\0' };
printf("%s", str1);
printf("%s", str2);
printf("str1 == str2?\n");
if (str1 == str2) {
printf("yes!\n");
} else {
printf("no!\n");
}
printf("str1[0] == str2[0]?\n");
if (str1[0] == str2[0]) {
printf("yes!\n");
} else {
printf("no!\n");
}
printf("%d\n", strncmp(str1, str2, 8));
if (strncmp(str1, str2, 8) == 0) {
printf("yes!\n");
} else {
printf("no!\n");
}
}
The strcmp() function compares the two strings s1 and s2. The locale is not taken into account (for a locale-aware comparison, see strcoll(3)). The comparison is done using unsigned characters. strcmp() returns an integer indicating the result of the comparison, as follows: • 0, if the s1 and s2 are equal; • a negative value if s1 is less than s2; • a positive value if s1 is greater than s2. The strncmp() function is similar, except it compares only the first (at most) n bytes of s1 and s2.
Reading strings
fgets with size less than some given value
#include <stdio.h>
int main(int argc, char **argv) {
int destlen = 20;
char dest[destlen];
// try less than, equal to, and greater than destlen (null terminator?)
fgets(dest, destlen, stdin);
printf("%s\n", dest);
}
gets, never use this function
gets(3) Library Functions Manual gets(3)
NAME
gets - get a string from standard input (DEPRECATED)
LIBRARY
Standard C library (libc, -lc)
SYNOPSIS
#include <stdio.h>
[[deprecated]] char *gets(char *s);
DESCRIPTION
Never use this function.
fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s.
Reading stops after an EOF or a newline. If a newline is read, it is stored into the buffer. A terminating null
byte ('\0') is stored after the last character in the buffer.
Copying strings
strlcpy
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv) {
char str[] = "hello!";
int destlen = 3;
/* int destlen = 20; */
char dest[destlen];
strlcpy(dest, str, destlen);
printf("%s\n", dest);
}
If we just try to copy using assignment, we will overwrite the original string.
strlcpy and strlcat - consistent, safe, string copy and concatenation.