Lecture 9: C to LC-3
@NCStateECE
Connect to slido.com
#ece209
ECE 209
Computer Systems Programming
Spring 2021
Lectures 15 & 16: Strings
Announcements
Z7: 3/30
PS4: 3/31
Program 2: 4/9
Photo by Andrea Piacquadio from Pexels
https://www.pexels.com/@olly?utm_content=attributionCopyText&utm_medium=referral&utm_source=pexels
https://www.pexels.com/photo/cheerful-young-woman-screaming-into-megaphone-3761509/?utm_content=attributionCopyText&utm_medium=referral&utm_source=pexels
String Traversal
int count = 0;
char *sp = str;
while (*sp++) count += 1;
int count = 0;
int i = 0;
while (str[i]) {
count += 1;
i += 1;
}
The data tells us when to stop.
String data must contain a null terminator.
a l p h a \0 & z * k Mstr
char str[11];
sp sp sp sp sp sp
int count = 0;
char *sp = str;
while (*sp++) count += 1;
sp
Null terminator is critical!
Without it, will keep moving
through memory until we find
a zero.
String Comparison
Which of these strings comes first?
(In ASCII order.)
f o x \0s1
a l p h a \0s2
String Comparison
f o x \0s1
a l p h a \0s2
if (s1 < s2) ...
Does this work?
To compare strings,
must look at the data.
String Comparison
f o x \0s1
a l p h a \0s2
if (*s1 < *s2) ...
Does this work?
String Comparison
a l p \0a c as1
a l p h a \0s2
if (*s1 < *s2) ...
Does this work?
String Comparison
a l p \0a c as1
a l p h a \0s2
If chars match, must look at next char.
String Comparison
a l p \0a c as1
a l p h a \0s2
If chars match, must look at next char.
String Comparison
a l p \0a c as1
a l p h a \0s2
If chars match, must look at next char.
String Comparison
a l p \0a c as1
a l p h a \0s2
If chars don't match, we have a winner.
'a' < 'h', so first string less than second.
String Comparison
a l p \0h as1
a l p h a \0s2
If both are null char, string are equal.
String Comparison
a l p \0h as1
a l p h a \0b e ts2
If one is shorter, it will be first.
(Not a special rule -- chars are different and '\0' is smaller.)
String Comparison
a l p \0a c as1
a l p h a \0s2
bool lessThan(char *s1, char *s2) {
while (*s1 == *s2) ...
String Comparison
a l p \0a c as1
a l p h a \0s2
bool lessThan(char *s1, char *s2) {
while (*s1 == *s2) {s1++; s2++;}
...
}
String Comparison
a l ps1
a l p h a \0s2
bool lessThan(char *s1, char *s2) {
while (*s1 == *s2) {s1++; s2++;}
return *s1 < *s2;
}
h a \0
What happens next?
String Comparison
a l ps1
a l p h a \0s2
bool lessThan(char *s1, char *s2) {
while (*s1 == *s2) {s1++; s2++;}
return *s1 < *s2;
}
h a \0
Which is greater?
String Comparison
a l ps1
a l p h a \0s2
bool lessThan(char *s1, char *s2) {
while (*s1 && (*s1 == *s2)) {s1++; s2++;}
return *s1 < *s2;
}
h a \0
What happens next?
const Pointer
bool lessThan(const char *s1, const char *s2) {
while (*s1 && (*s1 == *s2)) {s1++; s2++;}
return *s1 < *s2;
}
"pointer to a const char"
This means that the data being pointed to
cannot be changed using this pointer.
Cannot store to *s1. But s1 (the pointer) can be changed.
String Library Functions
String Inspection
size_t strlen(const char *s);
Returns the number of characters in the string.
Does not count the null terminator.
This is a standard type used to represent the length of something.
It’s an unsigned int. Can assign to an int variable.
CLion may flag conversion from unsigned to int — ignore it.
size_t strlen(const char *s);
Returns the number of characters in the string.
Does not count the null terminator.
Reminder — this is a function declaration.
It is NOT how we call the function.
x = strlen(s);
This is how we call a function.
No type information in the call.
int strcmp(const char *s1, const char *s2);
Compares two strings.
Returns 0 if the strings are equal.
Returns a negative number if first string is less than second.
Returns a positive number if first string is greater than second.
DO NOT assume that strcmp will return -1 or +1.
The actual value returned is not defined, up to the library implementor.
int strcasecmp(const char *s1, const char *s2);
Compares two strings, ignoring upper/lower-case.
Returns 0 if the strings are equal.
Returns a negative number if first string is less than second.
Returns a positive number if first string is greater than second.
DO NOT assume that strcasecmp will return -1 or +1.
The actual value returned is not defined, up to the library implementor.
This is not a standard function, but it is very common.
int strncmp(const char *s1, const char *s2,
size_t n);
Compares at most n characters of two strings.
Returns 0 if the strings are equal.
Returns a negative number if first string is less than second.
Returns a positive number if first string is greater than second.
DO NOT assume that strncmp will return -1 or +1.
The actual value returned is not defined, up to the library implementor.
char * strchr(const char *s1, int c);
Returns pointer to first occurrence of character c in the string.
Returns NULL (zero) if there is no occurrence.
Why is c an integer?
Often, we don’t care about the specific location.
We just want to know whether the character is present or not.
if (strchr(s, ‘?’)) …
char * strchr(const char *s1, int c);
Returns pointer to first occurrence of character c in the string.
Returns NULL (zero) if there is no occurrence.
Why is c an integer?
char * strrchr(const char *s1, int c);
Returns pointer to last occurrence of character c in the string.
Returns NULL (zero) if there is no occurrence.
char * strstr(const char *s, const char *sub);
Returns pointer to first occurrence of substring in the string.
Returns NULL (zero) if there is no occurrence.
If sub points to an empty string, s is returned.
String Declaration and
Allocation: Pointer vs Array
a b c d \0
char * s;
This is a pointer. It takes up one word in LC-3 memory.
It presumably points to an array of char, terminated by a null char.
But the char array is NOT allocated by this declaration.
Sometimes, we get lazy and say, “s is a string.”
You must understand that s is really a pointer to string data.
a b c d \0
const char * t;
This is a pointer. It takes up one word in LC-3 memory.
It presumably points to an array of char, terminated by a null char.
The char array is read-only, cannot store to *t.
The array is not allocated by this declaration.
read-only
Sometimes, we get lazy and say, “t is a string.”
You must understand that t is really a pointer to read-only string data.
Could be
a literal
string.
a b c d \0
char str[6];
This is an array. It takes up six words in LC-3 memory.
It may contain string data, or it may just contain six chars.
The array is allocated on the stack, or in the global data space.
Sometimes, we get lazy and say, “str is a string.”
You must understand that str is really an array that
may hold string data.
a b c d \0
char * s;
a b c d \0
const char * t;
read-only
a b c d \0
char str[6];
You must understand
the differences.
Initialization
a b c d \0
char * s = “abcd”;
a b c d \0
const char * t = “abcd”;
read-only
a b c d \0
char str[6] = “abcd”;
\0
Dangerous!
You must understand
the differences.
a b c d \0
char * sa[3];
This is an array of pointers.
It takes up three words in LC-3 memory.
Each element points to an array of char.
(They may even point to the same arrays!)
But the char arrays are NOT allocated by this declaration.
x y z \0
char sb[3][6];
This is an array of arrays.
It takes up 18 (3 * 6) words in LC-3 memory.
a b c d \0
x y z \0
a b c d \0
Number of char arrays.
Size of each char array.
a b c d \0
char * sa[3];
x y z \0
char sb[3][6];
a b c d \0
x y z \0
a b c d \0
You must understand
the differences.
a b c d \0
const char * sa[3] = {“abcd”, “xyz”, “abcd”};
x y z \0
char sb[3][6] = {“abcd”, “xyz”, “abcd”};
a b c d \0
x y z \0
a b c d \0
Initialization
String Library Functions
String Manipulation
char * strcpy(char *dest, const char *src);
Copies the characters from src to dest,
up to and including the null terminator.
(Overwrites previous data stored in dest.)
Returns dest.
dest MUST point to an array with enough space to hold the string.
dest and src may not be overlapping — undefined behavior.
b u r \0r i t o ss1
t a c o s \0s2
strcpy(s1, s2);
t a c \0o s o ss1
t a c o s \0s2
\0
char * strncpy(char *dest, const char *src,
size_t n);
Copies at most n characters from src to dest.
If n chars includes the null terminator, it is copied (and additional
null chars are written to dest, if needed.)
If n chars does not include the null terminator,
then dest will not be null-terminated!
dest MUST point to an array with enough space to hold the string.
dest and src may not be overlapping — undefined behavior.
b u r \0r i t o ss1
t a c o s \0s2
strncpy(s1, s2, 6);
t a c \0o s o ss1
t a c o s \0s2
\0
b u r \0r i t o ss1
t a c o s \0s2
strncpy(s1, s2, 5);
t a c \0o s o ss1
t a c o s \0s2
t
NOTE:
strcpy(s1, s2) is not the same as
strncpy(s1, strlen(s2))
b u r \0r i t o ss1
t a c o s \0s2
strncpy(s1, s2, 10);
t a c \0o ss1
t a c o s \0s2
\0 \0 \0 \0
char * strcat(char *dest, const char *src);
Appends the characters from src to the end of dest,
up to and including the null terminator.
Returns dest.
dest MUST point to an array with enough space to hold the string.
dest and src may not be overlapping — undefined behavior.
c a t \0s1
d o g \0s2
strcat(s1, s2);
c a t \0d o gs1
d o g \0s2
char str1[25] = “Wolfpack”;
char str2[25] = “Wins”;
char *p;
p = strchr(str1,’p’);
*p = toupper(*p);
strcat(str1, str2);
What is stored in str1 when this code executes?
Don’t answer in the chat — write it down and
wait for the Slido question.
I/O with Strings
Printing
Print a literal string — no format code needed!
printf(“Hello.\n”);
Print using a string pointer — %s
char myString[44];
…
printf(“My string: %s\n”, myString);
Expression — must be a char*.
Remember: name of an array is a pointer!
Printing
Print using a string pointer — %s
char * w = “string with many words”;
…
// Is this legal?
// What will be printed?
printf(“%s\n”, strrchr(w,’ ‘)+1);
Expression? Is it a char*?
Printing
Print using a string pointer — %s
printf(“%s”, “Hello\n”);
Yes, you can do this, but why would you?
printf(“Hello\n”);
We have a string array declared thusly: char str[4][10]; How can
we print string i?
ⓘ Start presenting to display the poll results on this slide.
Reading
Read a string — %s
char myString[44];
…
scanf(“%s”, myString);
Expression — must be a char*, and
must point to an array with enough space to hold the data,
including the null terminator.
scanf will:
1. Skip any space-like char.
2. Read and store all chars
until the next space-like char.
3. Terminate with a null character.
Reading
Read a string — %s
char * input;
…
scanf(“%s”, input);
Expression — must be a char*, and
must point to an array with enough space to hold the data.
Legal! But will most likely crash your program.
(Where does input point?)
Reading
Read a string — %s
char myString[44];
…
scanf(“%s”, myString);
What if the user enters 50 characters?
Will write past the bounds of the array.
May (or may not) crash.
Reading
Read a string — %s
char myString[44];
…
scanf(“%43s”, myString);
Will match and store up to 43 chars (or until next space).
Will always terminate with null.
Next character(s) will remain on the input stream.
If you don’t know how much space is in the array, good luck!
We have char name[12]; What is the safest way to read a name
from the user?
ⓘ Start presenting to display the poll results on this slide.
Reading
What if my input has spaces in it?
Can read multiple strings and stitch them together.
Use strcpy/cat or use pointer.
char input[80];
int i, n;
// read n words separated by spaces
// option 1: separate array, strcpy/strcat
for (i=0; i
We’ll get to this soon.
For now, just use stdin.
char input[80];
int i, n;
// read n words separated by spaces
// option 3: fgets
// actually, there’s no way to control how many words
// are read — depends on what the user types
fgets(input, 80, stdin); // read line from stdin
// remove linefeed at the end
char * ip = input + strlen(input) – 1;
if (*ip == ‘\n’) *ip = ‘\0’; // terminate
Lectures 15 & 16: Strings
Slide Number 2
String Traversal
Slide Number 4
String Comparison
String Comparison
Slide Number 8
String Comparison
String Comparison
String Comparison
String Comparison
String Comparison
String Comparison
String Comparison
String Comparison
String Comparison
String Comparison
String Comparison
String Comparison
String Comparison
const Pointer
Slide Number 24
Slide Number 25
Slide Number 26
Slide Number 28
Slide Number 29
Slide Number 30
Slide Number 31
Slide Number 32
Slide Number 33
Slide Number 35
Slide Number 36
Slide Number 37
Slide Number 38
Slide Number 39
Initialization
Slide Number 45
Slide Number 46
Slide Number 49
Initialization
Slide Number 52
Slide Number 53
Slide Number 54
Slide Number 55
Slide Number 56
Slide Number 57
Slide Number 58
Slide Number 59
Slide Number 60
Slide Number 61
Slide Number 63
Printing
Printing
Printing
Slide Number 67
Reading
Reading
Reading
Reading
Slide Number 72
Reading
Slide Number 74
Slide Number 75
Reading a Line of Text
Slide Number 77