Strings in C
char arrays, the zero byte, safe copying and reading a line.
A C string is a char array that ends with the zero byte '\0'. Every function in <string.h> walks the array until it finds that byte, so a missing terminator makes them read past the end.
#include <ctype.h>
#include <stdio.h>
#include <string.h>
int main(void) {
char full[40];
snprintf(full, sizeof full, "%s %s", "Training", "Trains");
printf("%s\n", full);
printf("%zu\n", strlen(full));
printf("%d\n", strcmp("apple", "apple"));
printf("%d\n", strcmp("apple", "banana") < 0);
char word[] = "erode";
for (int i = 0; word[i] != '\0'; i++) {
word[i] = (char) toupper((unsigned char) word[i]);
}
printf("%s\n", word);
return 0;
}Training Trains 15 0 1 ERODE
Use snprintf instead of sprintf or strcat: it is told the buffer size and never writes past it. strcmp returns 0 when two strings are equal. Never compare strings with ==, which only compares their addresses.
Reading a line safely
char name[32];
if (fgets(name, sizeof name, stdin) != NULL) {
name[strcspn(name, "\n")] = '\0';
printf("Hello, %s\n", name);
}fgets stops at the buffer size. gets could not, which is why it was removed from C. fgets keeps the newline, and strcspn finds it so you can cut it off.
Write your own string functions
#include <stdio.h>
#include <string.h>
void reverse(char *s) {
size_t n = strlen(s);
for (size_t i = 0; i < n / 2; i++) {
char t = s[i];
s[i] = s[n - 1 - i];
s[n - 1 - i] = t;
}
}
int countVowels(const char *s) {
int count = 0;
for (; *s != '\0'; s++) {
if (strchr("aeiouAEIOU", *s) != NULL) {
count++;
}
}
return count;
}
int main(void) {
char word[] = "Vanakkam";
printf("%d\n", countVowels(word));
reverse(word);
printf("%s\n", word);
return 0;
}3 makkanaV
char word[] = "Vanakkam" makes a copy that you may change. char *word = "Vanakkam" points at read-only memory, and changing it crashes the program.