Runtime verified Test scripts included

Syntax

Char(characterCode[, numRepetitions])  →  string
1–2 arguments

Parameters

Name Type Required Description
characterCode string | number Yes Character code, as a whole number
numRepetitions string | number No Number of times to repeat the returned character, as a whole number

Example

%%[
  VAR @letter
  SET @letter = Char(65)
]%%
Letter: %%=v(@letter)=%%

Renders Letter: A.

The usual reason to reach for it is a character you cannot type into the source safely — a quote inside a quoted string, or a line break:

%%[
  VAR @quoted
  SET @quoted = Concat(Char(34), AttributeValue("ProductName"), Char(34))
]%%

Return value

string — the character for the supplied code, repeated when a repetition count is given.

The value domain is open: any code that resolves produces its character, and a repetition count of 0 produces the empty string. There is no closed set of sentinel values to test for.

Behaviour

The optional second argument repeats the character. Char(65,3) gives AAA and Char(65,1) gives A. A count of 0 produces an empty string — Length(Char(65,0)) is 0.

Numeric strings are accepted for both parameters. Char("65") gives the same A as the numeric literal, and Char(65,"3") gives the same AAA.

Extended-ASCII codes resolve to their Latin-1 character. Char(190) and Char(255) each render a single character, at codepoint 190 and 255 respectively rather than as a multi-byte sequence.

Control codes are produced verbatim. Char(0), Char(9), Char(10), Char(13) and Char(32) each return one character — including the NUL byte, which renders as codepoint 0 in the response and measures Length 1. They are invisible in rendered output, so measure them rather than looking at them.

A decimal code, a decimal repeat count, a negative repeat count, a boolean, and a non-numeric string all abort the page. Char(65.7), Char(65,2.5), Char(65,-1), Char(true) and Char("abc") each aborted the page with HTTP 422, so nothing on the page survives. There is no error value to test for — guard the arguments before the call.

The code domain is not capped at 255

This is the load-bearing finding, and the official reference frames the domain as extended ASCII without saying what a larger number does.

Call Renders
Char(256) the character at codepoint 256
Char(9731) the character at codepoint 9731
Char(-1) the character at codepoint 65535
Char(65601) A — codepoint 65
Char(128512) the character at codepoint 62976

Codes are treated as 16-bit code-unit values, not as bytes and not as full Unicode codepoints. Anything at or above 65536 wraps: 65601 is 65601 - 65536 = 65, which is why it renders A, and a code in the astral range collapses to a single unrelated code unit instead of the emoji a caller might expect. Every one of these returned Length 1, so the function never produces a surrogate pair.

Each literal above occupies a single codepoint in the response, which is what distinguishes the intended character from a mis-decoded multi-byte sequence.

The capability is catalogued on Differs from official docs. The docs are silent here rather than wrong, so the entry is not flagged as contradicting them — but a code outside 0–255 has no documented contract, so do not lean on it for portability.

Show test script
%%[
  VAR @b
  SET @b = RequestParameter("b")

  /* documented forms: printable codes, extended ASCII, the repeat count */
  IF @b == "safe" THEN
    OutputLine(Concat("C65=[", Char(65), "]"))
    OutputLine(Concat("C97=[", Char(97), "]"))
    OutputLine(Concat("C48=[", Char(48), "]"))
    OutputLine(Concat("C34=[", Char(34), "]"))
    OutputLine(Concat("C39=[", Char(39), "]"))
    OutputLine(Concat("C190=[", Char(190), "]"))
    OutputLine(Concat("C255=[", Char(255), "]"))
    OutputLine(Concat("LEN65=[", Length(Char(65)), "]"))
    OutputLine(Concat("LEN190=[", Length(Char(190)), "]"))
    OutputLine(Concat("LEN255=[", Length(Char(255)), "]"))
    OutputLine(Concat("R3=[", Char(65,3), "]"))
    OutputLine(Concat("R1=[", Char(65,1), "]"))
    OutputLine(Concat("LENR3=[", Length(Char(65,3)), "]"))
  ENDIF

  /* control and whitespace codes - read these as raw bytes, not on a console */
  IF @b == "cp" THEN
    OutputLine(Concat("P10=[", Char(10), "]"))
    OutputLine(Concat("P13=[", Char(13), "]"))
    OutputLine(Concat("P32=[", Char(32), "]"))
    OutputLine(Concat("P0=[", Char(0), "]"))
    OutputLine(Concat("P9=[", Char(9), "]"))
    OutputLine(Concat("LENC0=[", Length(Char(0)), "]"))
  ENDIF

  /* numeric strings are accepted for either parameter */
  IF @b == "sc" THEN
    OutputLine(Concat("SC=[", Char("65"), "]"))
  ENDIF

  IF @b == "sr" THEN
    OutputLine(Concat("SR=[", Char(65,"3"), "]"))
  ENDIF

  /* a zero repeat count yields an empty string */
  IF @b == "r0" THEN
    OutputLine(Concat("R0=[", Char(65,0), "]"))
    OutputLine(Concat("LENR0=[", Length(Char(65,0)), "]"))
  ENDIF

  /* codes past the documented 0-255 range still resolve */
  IF @b == "c256" THEN
    OutputLine(Concat("C256=[", Char(256), "]"))
    OutputLine(Concat("LENC256=[", Length(Char(256)), "]"))
  ENDIF

  IF @b == "cbig" THEN
    OutputLine(Concat("CBIG=[", Char(9731), "]"))
    OutputLine(Concat("LENCBIG=[", Length(Char(9731)), "]"))
  ENDIF

  /* out-of-range codes wrap into the 16-bit code-unit range */
  IF @b == "cn" THEN
    OutputLine(Concat("CN=[", Char(-1), "]"))
  ENDIF

  IF @b == "cwrap" THEN
    OutputLine(Concat("W65601=[", Char(65601), "]"))
    OutputLine(Concat("LENW=[", Length(Char(65601)), "]"))
  ENDIF

  IF @b == "castral" THEN
    OutputLine(Concat("AST=[", Char(128512), "]"))
    OutputLine(Concat("LENAST=[", Length(Char(128512)), "]"))
  ENDIF

  /* every branch below aborts the page: the start marker never renders */
  IF @b == "rn" THEN
    OutputLine(Concat("--- rn start ---"))
    OutputLine(Concat("RN=[", Char(65,-1), "]"))
  ENDIF

  IF @b == "cdec" THEN
    OutputLine(Concat("--- cdec start ---"))
    OutputLine(Concat("CDEC=[", Char(65.7), "]"))
  ENDIF

  IF @b == "rdec" THEN
    OutputLine(Concat("--- rdec start ---"))
    OutputLine(Concat("RDEC=[", Char(65,2.5), "]"))
  ENDIF

  IF @b == "cb" THEN
    OutputLine(Concat("--- cb start ---"))
    OutputLine(Concat("CB=[", Char(true), "]"))
  ENDIF

  IF @b == "cbad" THEN
    OutputLine(Concat("--- cbad start ---"))
    OutputLine(Concat("CBAD=[", Char("abc"), "]"))
  ENDIF

  IF @b == "a0" THEN
    OutputLine(Concat("--- a0 start ---"))
    OutputLine(Concat("A0=[", Char(), "]"))
  ENDIF

  IF @b == "a3" THEN
    OutputLine(Concat("--- a3 start ---"))
    OutputLine(Concat("A3=[", Char(65,2,3), "]"))
  ENDIF
]%%

Availability

Platform Available
Marketing Cloud Engagement Yes
Marketing Cloud Next No

See also