puts
, writes a string, followed by a newline.
puts("hello"); printf("hello\n");
hello hello
or:
char name[] = "Stephen Fry"; puts(name); printf("%s\n", name);
Stephen Fry Stephen Fry
Could use scanf("%s", string);
but…
char message[80]; printf("Enter a string:\n"); scanf("%s", message); printf("The string just entered is:\n"); puts(message); printf("The size is %zu:\n", strlen(message));
Why is there no &
for scanf
?
Could use scanf("%s", string);
but…
char message[80]; printf("Enter a string: "); scanf("%s", message); printf("You said \"%s\"\n", message); printf("Size: %zu\n", strlen(message));
Enter a string: Jack Applin You said "Jack" Size: 4
That wasn’t what I wanted!
fgets
function reads a string from a stream:
fgets(name, length, stdin);
'\n'
is encountered.
That is, it reads a line.
'\n'
, is included in the string.
char message[20]; printf("Enter a string: "); fgets(message, sizeof(message), stdin); printf("The string just entered is:\n"); puts(message); printf("The size is: %zu\n", strlen(message));
% ./a.out Enter a string: The end is near! The string just entered is: The end is near! The size is 17
Where did that blank line come from?
#include <stdio.h> int main() { char first[100], last[100]; printf("Enter your first name: "); fgets(first, sizeof(first), stdin); printf("Enter your last name: "); fgets(last, sizeof(last), stdin); printf("Your name is: %s %s\n", first, last); return 0; }
% c11 example.c % ./a.out Enter your first name: Cookie Enter your last name: Monster Your name is: Cookie Monster
That looks awful. We need to remove the newline from the end of the strings.
// Chop the last character '\n' off the strings firstName[strlen(firstName)-1] = '\0'; lastName[strlen(lastName)-1] = '\0'
Why the -1
?
char s[] = "bonehead"; s[4] = '\0'; printf("%s\n", s);
bone
┌────┬────┬────┬────┬────┬────┬────┬────┬────┐ │ b │ o │ n │ e │ h │ e │ a │ d │ \0 │ └────┴────┴────┴────┴────┴────┴────┴────┴────┘ ┌────┬────┬────┬────┬────┬────┬────┬────┬────┐ │ b │ o │ n │ e │ \0 │ e │ a │ d │ \0 │ └────┴────┴────┴────┴────┴────┴────┴────┴────┘
scanf
to read
numbers from the keyboard.
fgets
to read input as a string is a better
approach, but how do we convert the string to a number?
sscanf
(notice the extra s
) acts like
scanf
, but on strings rather than standard input.
sscanf(
string, format, variables)
#include <stdio.h> int main() { char line[400]; float height, weight; // read two numbers from a user on one line printf("Enter your height and weight: "); fgets(line, sizeof(line), stdin); // read the two numbers from the string to two floats sscanf(line, "%f %f", &height, &weight); return 0; }
#include <string.h>
Name | Description |
---|---|
strcpy(s1, s2) | Copies s2 to s1 |
strcat(s1, s2) | Concatenates s2 onto s1 |
strlen(s) | Returns the length of s |
strchr(s, c) | Finds first occurrence of c in s |
strcmp(s1, s2) | Compares s1 to s2 |
char buf[80]; strcpy(buf, "housecat"); puts(buf); strcpy(buf, "dog"); puts(buf);
housecat dog
char buf[80]; strcpy(buf, "housecat"); puts(buf); strcat(buf, "dog"); puts(buf);
housecat housecatdog
char buf[80] = "The quick brown fox jumped over a lazy dog."; puts(buf); char *p = strchr(buf, 'x'); if (p == NULL) puts("Not found"); else *p = 'g'; puts(buf);
The quick brown fox jumped over a lazy dog. The quick brown fog jumped over a lazy dog.
char g[] = "gamma", o[] = "omega", z[] = "ZETA"; if (strcmp(g, o) < 0) printf("%s comes before %s\n", g, o); if (strcmp(g, o) == 0) printf("%s and %s are the same\n", g, o); if (strcmp(g, o) > 0) printf("%s comes after %s\n", g, o); if (strcmp(g, z) < 0) printf("%s comes before %s\n", g, z); if (strcmp(g, z) == 0) printf("%s and %s are the same\n", g, z); if (strcmp(g, z) > 0) printf("%s comes after %s\n", g, z);
gamma comes before omega gamma comes after ZETA
Don’t count on the relative order of upper- and lower-case letters, or letters & numbers, punctuation, etc.
Name | Description |
---|---|
isalpha(c) | Is this a letter? |
isupper(c) | Is this an uppercase letter? |
islower(c) | Is this a lowercase letter? |
isdigit(c) | Is this a digit? |
isspace(c) | Is this a whitespace? |
toupper(c) | Convert char to uppercase |
tolower(c) | Convert char to lowercase |
#include <ctype.h>
0
for false, and something else for true.
char
—not a string!
ctype.h
example #1#include <stdio.h> #include <ctype.h> int main() { char s[] = "Jack 2.0"; for (int i=0; s[i]; i++) { printf("%c:", s[i]); if (isalpha(s[i])) printf(" alpha"); if (isupper(s[i])) printf(" upper"); if (islower(s[i])) printf(" lower"); if (isdigit(s[i])) printf(" digit"); if (isspace(s[i])) printf(" space"); printf("\n"); } }
J: alpha upper a: alpha lower c: alpha lower k: alpha lower : space 2: digit .: 0: digit
ctype.h
example #2#include <stdio.h> #include <ctype.h> int main() { char s[] = "Bonehead 2.0"; puts(s); // Convert to upper case for (int i=0; s[i]; i++) s[i] = toupper(s[i]); puts(s); // Convert to lower case for (int i=0; s[i]; i++) s[i] = tolower(s[i]); puts(s); }
Bonehead 2.0 BONEHEAD 2.0 bonehead 2.0
#include <stdlib.h>
Name | Description |
---|---|
atoi(s) | Convert string to int |
atof(s) | Convert string to double |
atoi
= ASCII to integer atof
= ASCII to floating-point value
strcpy
actually work?
void mystrcpy(char to[], char from[]) { for (int i=0; i<=strlen(from); i++) to[i] = from[i]; }
<=
?
strlen
called?
Let’s avoid calling strlen
so many times:
void mystrcpy(char to[], char from[]) { int len = strlen(from); for (int i=0; i<=len i++) to[i] = from[i]; }
strlen
really do? Is it cheap?
It’s faster to avoid calling strlen
, if we care:
void mystrcpy(char to[], char from[]) { int i=0; while (from[i] != '\0') { to[i] = from[i]; i++; } to[i] = '\0'; }
#define CONST_NAME value
char
array, the best approach is
to make the loop condition quit once it encounters a null character.
NULL
) character '\0'
.
'\n'
is in your string,
even though it’s hard to see.
#include
<string.h>
, <ctype.h>
,
or <stdlib.h>
.
=
, ==
, !=
, <
, >
, <=
, >=
on strings.