Reading numbers with scanf#
scanf reads from the keyboard using the same placeholders as printf, with one difference: you pass the address of each variable, written with &:
int a, b;
scanf("%d %d", &a, &b);
printf("%d\n", a + b);
&a means "where a lives in memory". scanf needs that to put the value there. Forgetting the & is a classic crash.
For long long use %lld, and for double use %lf (with scanf; printf uses %f for doubles).
scanf returns how many values it read, which lets you read until the input runs out:
int x;
long long total = 0;
while (scanf("%d", &x) == 1) {
total += x;
}
Strings are character arrays#
C has no string type. A string is an array of char ending in a special character, '\0', called the null terminator, that marks the end:
char name[] = "Asha";
// stored as: 'A' 's' 'h' 'a' '\0' -- five bytes, not four
Everything about C strings follows from this. Their length is found by walking to the '\0', and an array must have room for it.
char word[6] = "hello"; // 5 letters + '\0' = 6: fits exactly
char tiny[5] = "hello"; // no room for '\0': not a proper string
Reading a word#
char word[100];
scanf("%99s", word); // no &: an array name is already an address
%s stops at the first space. The 99 limits how much is read, leaving room for the '\0' in an array of 100, so long input cannot overflow it.
Reading a whole line#
fgets reads a line including spaces, and never more than you allow:
char line[200];
fgets(line, sizeof line, stdin);
line[strcspn(line, "\n")] = '\0'; // remove the newline fgets keeps
Never use gets. It has no size limit and was removed from the language because of it.
string.h#
#include <string.h>
strlen("hello") // 5: counts up to '\0'
strcpy(dest, src) // copy src into dest (dest must be big enough)
strcat(dest, src) // append src to dest
strcmp(a, b) // 0 if equal, negative or positive otherwise
strchr(s, 'x') // pointer to the first 'x', or NULL
Two rules that catch everyone:
- Compare strings with
strcmp, never==.a == bcompares addresses, so two strings with the same letters are "not equal". strlenwalks the whole string every time. Do not put it in a loop condition; call it once.
int n = strlen(s);
for (int i = 0; i < n; i++) { ... }
Walking a string#
Loop until the terminator, or to the length:
int vowels = 0;
for (int i = 0; s[i] != '\0'; i++) {
char c = tolower(s[i]); // <ctype.h>
if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') {
vowels++;
}
}
<ctype.h> has isalpha, isdigit, isalnum, isspace, tolower and toupper.
Key points#
scanfneeds&before each number variable;%lfreads a double.- A string is a
chararray ending in'\0', which needs a byte of its own. - Limit what
%sreads (%99s), and read lines withfgets, nevergets. - Compare with
strcmp, not==; callstrlenonce, not in a loop.
Next: making decisions with if and switch.