{ }codelper

Learn › Craykon

Data · 11

Working with single characters

One character as a value: its code, letter arithmetic, the i-th character, repeating.

A single character is a value too.
Inside it is a number (its code), so you can add and subtract.
The example below reads a string like c2a3z1, where a lowercase letter and a digit alternate, two characters at a time and prints, on each line, the letter, its code, the next letter of the alphabet, and the letter repeated as many times as the digit says.

s = Console.ReadLine().Trim();a = Str.Code("a");for (i = 0; i < s.Length; i += 2){    ch = s[i]; // i번째 글자    count = s[i + 1].ToNumber(); // 숫자 글자 → 수    code = Str.Code(ch);    after = Str.FromCode(a + (code - a + 1) % 26); // 다음 글자(z 다음은 a)    Console.WriteLine(ch + " " + code + " " + after + " " + ch.Repeat(count));}
stdin
c2a3z1
stdout
c 99 d cc
a 97 b aaa
z 122 a z

Key points

  • C, C++, Java and C# have a type char that holds exactly one character, written with single quotes ('a').
    Python, JavaScript and Craykon have no such type: one character is just a string of length 1.
  • Letter arithmetic: the codes of the alphabet are consecutive (a 97, b 98, …).
    So ch - 'a' tells how many steps after a the letter is (0–25), and 'a' + k is the letter k steps after a.
    In languages without char, convert to a code, calculate, then convert back to a character.
  • A digit character is not a number.
    The code of '7' is 55.
    To get the number 7, subtract the code of '0' ('7' - '0') or use a to-number function.
  • Take the i-th character with s[i] (Java: s.charAt(i)).
    The last character is at length - 1.
    Reading past it stops with an error in some languages, quietly gives undefined in others, and in C and C++ is not checked at all, so what happens is not defined.
  • Repeating joins the same string n times.
    "ab" three times is "ababab", and zero times is the empty string.
    It lets you print stars or rules without a loop.

How each language writes it

PythonCode ord(ch), back to a character chr(n) — the next letter is chr(ord(ch) + 1).
Digit character: int(ch).
s[i], and from the end s[-1].
Out of range raises IndexError.
Repeat: ch * 3
JavaScriptCode ch.charCodeAt(0), back to a character String.fromCharCode(n).
Digit character: Number(ch).
s[i], and from the end s.at(-1).
Out of range, s[9] is undefined with no error.
Repeat: ch.repeat(3)
TypeScriptSame as JavaScript
Javachar ch = s.charAt(i) — s[i] is not allowed.
Code: int code = ch; back to a character: (char) (ch + 1).
Digit character: ch - '0'.
Out of range throws StringIndexOutOfBoundsException.
Only strings can repeat: String.valueOf(ch).repeat(3)
C#char ch = s[i], last is s[^1].
Code: int code = ch; back to a character: (char)(ch + 1).
Digit character: ch - '0'.
Out of range throws IndexOutOfRangeException.
Repeat a character: new string(ch, 3)
C++char ch = s[i] — a char is simply a small integer, so ch + 1 and ch - '0' work directly.
s[i] does not check the range, so reading an index greater than the length is undefined behaviour (a garbage value or a crash); s.at(i) checks and throws std::out_of_range.
Repeat a character: std::string(3, ch) (count first)
Cchar ch = s[i] — as in C++, a char is a small integer.
In printf, %c prints it as a character and %d as its code.
s[length] holds the end marker \0; reading beyond that is not checked and is undefined behaviour (a garbage value or a crash).
There is no repeat, so print in a loop
CraykonCode Str.Code(ch), back to a character Str.FromCode(n).
Digit character: ch.ToNumber().
s[i] — out of range stops with the error "string only has indexes 0–2" (negative indexes too).
Repeat: ch.Repeat(3)

Common mistakes

Adding 1 to a one-character stringPython · JavaScript · TypeScript · Craykon

print("a" + 1)

→ Python raises TypeError: can only concatenate str (not "int") to str. JavaScript, TypeScript and Craykon give a1 with no error — the number is appended

Convert to a code, add, and convert back: Python chr(ord("a") + 1), JavaScript String.fromCharCode("a".charCodeAt(0) + 1), Craykon Str.FromCode(Str.Code("a") + 1).

Adding 1 to a character and printing it gave a numberJava · C# · C++

System.out.println('a' + 1);   // Java
Console.WriteLine('a' + 1);    // C#
std::cout << 'a' + 1;          // C++

→ All three print 98 — adding a number to a char gives an int

Convert back to a character: (char) ('a' + 1) → b.
For the same reason, char c = 'a'; c = c + 1; is a compile error in Java and C#; write c++ or c = (char) (c + 1).

Using a digit character as if it were the numberC · C++ · Java · C#

char ch = '7';
int n = ch;
printf("%d\n", n);

→ 55 — not 7 but the code of '7'

Subtract '0': ch - '0' → 7.
It works because the codes of the digit characters are consecutive, starting at '0' (48).

How languages differ
Repeating is easy to confuse with multiplying.
In Python "3" * 2 is "33", not 6, so multiplying input you forgot to convert repeats the string instead.
JavaScript goes the other way ("3" * 2 is 6), TypeScript gives a compile error, and Craykon stops with "* only works on two numbers".
In C++ std::string(3, '*') takes the count first.
Swap them into std::string('*', 3) and you get, with no error, a wrong 42-character string (the code of '*' is 42).

Practice