Here are 13 problems, from beginner to advanced, that use the char type and strings (arrays of characters). In every problem, the key is to keep in mind the '\0' that marks the end of a string. Write your code in the browser and press "Check": it is run with real gcc on several inputs to see whether the output is correct.
Note: Run and Check send your code to Wandbox, a free external compiler service, and run it with gcc.
strlen; count it yourself."Run" executes your code with the input above. "Check" tests it against 4 prepared inputs.
'\0' right after its last character. Increase an index len from 0 and stop when s[len] is '\0'; the value of len at that point is the length.#include <stdio.h> int main(void) { char s[100]; scanf("%99s", s); int len = 0; while (s[len] != '\0') { len++; } printf("Length: %d\n", len); return 0; }
'\0' is, and '\0' itself is not counted. The 99 in scanf("%99s", s) means "read at most 99 characters", leaving one slot for '\0' so that it doesn't overflow the array.character: code", one per line. Print the character code in decimal."Run" executes your code with the input above. "Check" tests it against 4 prepared inputs.
s[i] with %c to get the character, or with %d to get the number.#include <stdio.h> int main(void) { char s[100]; scanf("%99s", s); for (int i = 0; s[i] != '\0'; i++) { printf("%c: %d\n", s[i], s[i]); } return 0; }
'0' has the code 48, which is different from the number 0. Using the facts that "'0'–'9' have consecutive codes" (guaranteed by the C standard) and "'A'–'Z' and 'a'–'z' are each consecutive" (a property of ASCII), you can do conversions like the one in the next problem. With the loop condition s[i] != '\0', you can go to the end without computing the length first."Run" executes your code with the input above. "Check" tests it against 4 prepared inputs.
'a' <= c && c <= 'z', it is lowercase. In ASCII the difference between the codes of a lowercase letter and its uppercase letter is constant, so c - 'a' + 'A' gives the uppercase letter.#include <stdio.h> int main(void) { char s[100]; scanf("%99s", s); for (int i = 0; s[i] != '\0'; i++) { if ('a' <= s[i] && s[i] <= 'z') { s[i] = s[i] - 'a' + 'A'; } else if ('A' <= s[i] && s[i] <= 'Z') { s[i] = s[i] - 'A' + 'a'; } } printf("%s\n", s); return 0; }
else if to if, a character converted from lowercase to uppercase is immediately converted back from uppercase to lowercase. You can also use toupper / tolower from <ctype.h> (it is safest to pass the argument cast as (unsigned char)s[i])."Run" executes your code with the input above. "Check" tests it against 5 prepared inputs.
s[i] != '\0' and count when s[i] == c. Single characters can be compared with ==.#include <stdio.h> int main(void) { char s[100]; char c; scanf("%99s %c", s, &c); int count = 0; for (int i = 0; s[i] != '\0'; i++) { if (s[i] == c) count++; } printf("Count: %d\n", count); return 0; }
==, but strings cannot (that would compare the addresses of the start of the arrays). Use strcmp to compare strings. The space before %c in the format "%99s %c" skips the space after the string (because %c would otherwise read a space as a character).printf("%s\n", s)."Run" executes your code with the input above. "Check" tests it against 5 prepared inputs.
len, swap from both ends: s[0] with s[len - 1], s[1] with s[len - 2], and so on. You are done after len / 2 swaps.#include <stdio.h> #include <string.h> int main(void) { char s[100]; scanf("%99s", s); size_t len = strlen(s); for (size_t i = 0; i < len / 2; i++) { char tmp = s[i]; s[i] = s[len - 1 - i]; s[len - 1 - i] = tmp; } printf("%s\n", s); return 0; }
len times, after the halfway point the characters are swapped back to where they were. The partner position is len - 1 - i, not len - i (s[len] is '\0', and moving it to the front gives an empty string). strlen returns a size_t, so if you make the index a size_t too, you won't get warnings about mixing signed and unsigned.Palindrome" if it reads the same forwards and backwards (a palindrome), or "Not a palindrome" otherwise. Upper and lower case are distinguished."Run" executes your code with the input above. "Check" tests it against 6 prepared inputs.
s[i] with s[len - 1 - i]. If even one pair differs, it is not a palindrome, so set a flag to 0 and break.#include <stdio.h> #include <string.h> int main(void) { char s[100]; scanf("%99s", s); size_t len = strlen(s); int is_pal = 1; for (size_t i = 0; i < len / 2; i++) { if (s[i] != s[len - 1 - i]) { is_pal = 0; break; } } if (is_pal) { printf("Palindrome\n"); } else { printf("Not a palindrome\n"); } return 0; }
if (match) is wrong. The pattern "NG if even one place differs, OK if no difference is found by the end" is normally written with a flag variable. When the length is odd, the middle character would only be compared with itself, so you don't need to check it.letter: count", one per line, in order from a to z. Don't print letters that never appear."Run" executes your code with the input above. "Check" tests it against 4 prepared inputs.
int cnt[26] = {0};. A letter c becomes a number from 0 to 25 with c - 'a', so you can count with cnt[s[i] - 'a']++;.#include <stdio.h> int main(void) { char s[100]; scanf("%99s", s); int cnt[26] = {0}; for (int i = 0; s[i] != '\0'; i++) { cnt[s[i] - 'a']++; } for (int k = 0; k < 26; k++) { if (cnt[k] > 0) { printf("%c: %d\n", 'a' + k, cnt[k]); } } return 0; }
s[i] - 'a') with the "index → character" conversion ('a' + k). If the input contains anything other than lowercase letters, the index goes outside 0–25 and you write out of bounds, so in real code you check 'a' <= s[i] && s[i] <= 'z' before counting.Same string". Use strcmp for the comparison."Run" executes your code with the input above. "Check" tests it against 5 prepared inputs.
strcmp(a, b) returns a negative value if a comes first, 0 if they are the same, and a positive value if a comes after. If a comes after, swap the contents of a and b using a temporary array and strcpy, then print.#include <stdio.h> #include <string.h> int main(void) { char a[100], b[100]; scanf("%99s %99s", a, b); int r = strcmp(a, b); if (r == 0) { printf("Same string\n"); return 0; } if (r > 0) { char tmp[100]; strcpy(tmp, a); strcpy(a, b); strcpy(b, tmp); } printf("%s\n%s\n", a, b); return 0; }
strcmp is not necessarily −1 or 1, so test with > 0 / < 0, not == 1. Arrays can't be assigned, as in a = b;, so use strcpy to copy the contents. The comparison is by character code, so uppercase letters (65–90) come before lowercase letters (97–122) (Zoo comes before apple). Also, app is the beginning of apple, so the shorter one comes first.fgets (the input may not end with a newline)."Run" executes your code with the input above. "Check" tests it against 5 prepared inputs.
in_word meaning "we are currently inside a word". On a space (or newline), set in_word = 0; on any other character, if in_word is 0 it is the start of a word, so add 1 to the count and set in_word = 1.#include <stdio.h> int main(void) { char s[256]; if (fgets(s, sizeof s, stdin) == NULL) { s[0] = '\0'; } int count = 0, in_word = 0; for (int i = 0; s[i] != '\0'; i++) { if (s[i] == ' ' || s[i] == '\n') { in_word = 0; } else if (!in_word) { in_word = 1; count++; } } printf("Words: %d\n", count); return 0; }
fgets also stores the newline '\n' at the end of the line in the array (unless the input doesn't end with a newline), so here the newline is treated as a separator too. scanf("%s") stops reading at a space, so it can't read a line that contains spaces."Run" executes your code with the input above. "Check" tests it against 5 prepared inputs.
s[i] - 'a', add K, take the remainder when divided by 26, and add 'a' to turn it back into a letter. Uppercase letters work the same way, using 'A' as the base.#include <stdio.h> int main(void) { int k; char s[100]; scanf("%d %99s", &k, s); for (int i = 0; s[i] != '\0'; i++) { if ('a' <= s[i] && s[i] <= 'z') { s[i] = 'a' + (s[i] - 'a' + k) % 26; } else if ('A' <= s[i] && s[i] <= 'Z') { s[i] = 'A' + (s[i] - 'A' + k) % 26; } } printf("%s\n", s); return 0; }
s[i] + k, going past 'z' gives symbols such as {. Converting to a number from 0 to 25 first and then taking % 26 is the standard technique for calculations that wrap around in a circle. Encrypting twice with K=13 gives back the original (ROT13).my_strlen, which returns the length of a string, and the function my_strcat, which appends src to the end of the string dst, without using <string.h>. Use main exactly as in the template. The input is two strings with no spaces (each 1 to 49 characters), and the joined string and its length are printed."Run" executes your code with the input above. "Check" tests it against 4 prepared inputs.
my_strcat has two steps. (1) Find the position of '\0' in dst (that is where writing starts). (2) From there, copy src one character at a time, and write a '\0' at the end as well.#include <stdio.h> int my_strlen(const char *s) { int len = 0; while (s[len] != '\0') { len++; } return len; } void my_strcat(char *dst, const char *src) { int i = my_strlen(dst); int j = 0; while (src[j] != '\0') { dst[i] = src[j]; i++; j++; } dst[i] = '\0'; } int main(void) { char a[100], b[50]; scanf("%49s %49s", a, b); my_strcat(a, b); printf("%s\n", a); printf("Length: %d\n", my_strlen(a)); return 0; }
dst[i] = '\0';, there is no telling what follows the joined text, and printf may print garbage or keep reading past the end of the array. Also, the destination array a must be large enough for both lengths + 1 character (here 49 + 49 + 1 ≤ 100). The standard strcat doesn't check the size either, so the caller is responsible. The const on a parameter is a promise that "this function doesn't modify the contents".Anagram" if rearranging the letters of one gives the other (an anagram), or "Not an anagram" otherwise. Identical strings also count as anagrams."Run" executes your code with the input above. "Check" tests it against 6 prepared inputs.
int cnt[26] = {0};, add +1 for each letter of the first string and −1 for each letter of the second, then check whether all 26 counts are 0.#include <stdio.h> int main(void) { char a[100], b[100]; scanf("%99s %99s", a, b); int cnt[26] = {0}; for (int i = 0; a[i] != '\0'; i++) { cnt[a[i] - 'a']++; } for (int i = 0; b[i] != '\0'; i++) { cnt[b[i] - 'a']--; } int ok = 1; for (int k = 0; k < 26; k++) { if (cnt[k] != 0) { ok = 0; break; } } if (ok) { printf("Anagram\n"); } else { printf("Not an anagram\n"); } return 0; }
aab and abb. Comparing counts also naturally judges strings of different lengths (abc and ab) as different. Another approach is to sort each string and then compare them with strcmp.aaabccdddd becomes a3b1c2d4. Runs of a single character also get the count 1. Upper and lower case are treated as different characters."Run" executes your code with the input above. "Check" tests it against 6 prepared inputs.
c at index i, and increase i and the count while s[i] == c. When you reach a different character (or '\0'), print "c and the count" and start counting the next run from there.#include <stdio.h> int main(void) { char s[100]; scanf("%99s", s); int i = 0; while (s[i] != '\0') { char c = s[i]; int count = 0; while (s[i] == c) { count++; i++; } printf("%c%d", c, count); } printf("\n"); return 0; }
c is a letter, the inner while (s[i] == c) always stops when it reaches '\0' and never leaves the array. You can also write it by comparing s[i] == s[i + 1], but then it is easy to forget to print the last run, so be careful. The count can have two or more digits, so print it with %d ('0' + count breaks at 10 or more).