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, confirmed by dumping the response codepoints as 190 and 255 rather than a multi-byte misread.

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 returned HTTP 422 with no start marker rendered, 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 was read from a per-character codepoint dump of the response rather than from a console, because an extended-ASCII character and a mis-decoded multi-byte sequence are indistinguishable by eye.

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