---
id: strings
title: Strings
sidebar_label: Strings
---
Strings are used to store sequences of characters.
Strings are actually objects, so can be used where ever an object is expected.
Strings provide the following methods:
| Method | Description |
|---|---|
| `Find:Int( subString:String,startIndex=0 )` | Finds first occurance of a sub string. Returns -1 if **subString** not found. |
| `FindLast:Int( subString:String,startIndex=0 )` | Finds last occurance of a sub string. Returns -1 if **subString** not found. |
| `HashCode:UInt()` | Returns the calculated hash for the string. |
| `Trim:String()` | Removes leading and trailing non-printable characters from a string. |
| `Replace:String( subString:String,withString:String )` | Replaces all occurances of **subString** with **withString**. |
| `StartsWith:Int( subString:String )` | Returns true if string starts with **subString**. |
| `EndsWith:Int( subString:String )` | Returns true if string ends with **subString**. |
| `Contains:Int( subString:String )` | Returns true if string contains **subString**. |
| `Join:String( bits:String[] )` | Joins **bits** together by inserting this string between each bit. |
| `Split:String[]( separator$[] )` | Splits this string into bits delimited by **separator**. |
| `ToLower:String()` | Converts string to lowercase. |
| `ToUpper:String()` | Converts string to uppercase. |
| `ToInt:Int()` | Converts string to an integer. |
| `ToUInt:UInt()` | Converts string to an unsigned integer. |
| `ToLong:Long()` | Converts string to a long. |
| `ToULong:ULong()` | Converts string to an unsigned long. |
| `ToLongInt:LongInt()` | Converts string to a long integer. A LongInt can be 32 or 64 bits in size, depending on the OS and pointer size. |
| `ToULongInt:ULongInt()` | Converts string to an unsigned long integer. A ULongInt can be 32 or 64 bits in size, depending on the OS and pointer size. |
| `ToSizeT:Size_T()` | Converts string to a size_t. A Size_T can be 32 or 64 bits in size, depending on the system pointer size. |
| `ToFloat:Float()` | Converts string to a float. |
| `ToDouble:Double()` | Converts string to a double. |
| `ToCString:Byte Ptr()` | Converts string to a null terminated sequence of 8 bit bytes. The returned memory must eventually be freed with a call to [MemFree]. |
| `ToWString:Short Ptr()` | Converts string to a null terminated sequence of 16 bit shorts. The returned memory must eventually be freed with a call to [MemFree]. |
| `ToUTF8String:Byte Ptr()` | Converts string to a null terminated sequence of UTF-8 characters. The returned memory must eventually be freed with a call to [MemFree]. |
| `ToUTF8StringBuffer:Byte Ptr(buf:Byte Ptr, length:Size_T Var)` | Populates a pre-allocated buffer of **length** bytes with the string converted to a null terminated sequence of UTF-8 characters. On return, **length** contains the number of bytes copied to the buffer. |
| `ToDoubleEx:Int( val:Double Var,startPos:Int=0,endPos:Int=-1,format:Int=5,sep:String="."` | Converts a substring of this string to a double. The substring is defined by the range from **startPos** to **endPos**. If **endPos** is -1, the substring extends to the end of the string. The conversion process starts at **startPos** and continues until a valid double is parsed or the end of the substring is reached. The **format** parameter specifies one or more of the CHARSFORMAT flags (see below), and **sep** specifies the decimal separator character. The result of the conversion is stored in **val**, and the method returns the index of the first character in the substring that was not part of the valid double, or 0 if no valid double was found. |
| `ToFloatEx:Int( val:Float Var,startPos:Int=0,endPos:Int=-1,format:Int=5,sep:String="." )` | Converts a substring of this string to a float. The substring is defined by the range from **startPos** to **endPos**. If **endPos** is -1, the substring extends to the end of the string. The conversion process starts at **startPos** and continues until a valid float is parsed or the end of the substring is reached. The **format** parameter specifies one or more of the CHARSFORMAT flags (see below), and **sep** specifies the decimal separator character. The result of the conversion is stored in **val**, and the method returns the index of the first character in the substring that was not part of the valid float, or 0 if no valid float was found. |
| `ToIntEx:Int( val:Int Var,startPos:Int=0,endPos:Int=-1,format:Int=5,base:Int=10 )` | Converts a substring of this string to an integer. The substring is defined by the range from **startPos** to **endPos**. If **endPos** is -1, the substring extends to the end of the string. The conversion process starts at **startPos** and continues until a valid integer is parsed or the end of the substring is reached. The **format** parameter specifies one or more of the CHARSFORMAT flags (see below), and **base** specifies the numerical base for conversion (e.g., 10 for decimal, 16 for hexadecimal). The result of the conversion is stored in **val**, and the method returns the index of the first character in the substring that was not part of the valid integer, or 0 if no valid integer was found. |
| `ToUIntEx:Int( val:UInt Var,startPos:Int=0,endPos:Int=-1,format:Int=5,base:Int=10 )` | Converts a substring of this string to an unsigned integer. The substring is defined by the range from **startPos** to **endPos**. If **endPos** is -1, the substring extends to the end of the string. The conversion process starts at **startPos** and continues until a valid unsigned integer is parsed or the end of the substring is reached. The **format** parameter specifies one or more of the CHARSFORMAT flags (see below), and **base** specifies the numerical base for conversion (e.g., 10 for decimal, 16 for hexadecimal). The result of the conversion is stored in **val**, and the method returns the index of the first character in the substring that was not part of the valid unsigned integer, or 0 if no valid unsigned integer was found. |
| `ToLongEx:Int( val:Long Var,startPos:Int=0,endPos:Int=-1,format:Int=5,base:Int=10 )` | Converts a substring of this string to a long. The substring is defined by the range from **startPos** to **endPos**. If **endPos** is -1, the substring extends to the end of the string. The conversion process starts at **startPos** and continues until a valid long is parsed or the end of the substring is reached. The **format** parameter specifies one or more of the CHARSFORMAT flags (see below), and **base** specifies the numerical base for conversion (e.g., 10 for decimal, 16 for hexadecimal). The result of the conversion is stored in **val**, and the method returns the index of the first character in the substring that was not part of the valid long, or 0 if no valid long was found. |
| `ToULongEx:Int( val:ULong Var,startPos:Int=0,endPos:Int=-1,format:Int=5,base:Int=10 )` | Converts a substring of this string to an unsigned long. The substring is defined by the range from **startPos** to **endPos**. If **endPos** is -1, the substring extends to the end of the string. The conversion process starts at **startPos** and continues until a valid unsigned long is parsed or the end of the substring is reached. The **format** parameter specifies one or more of the CHARSFORMAT flags (see below), and **base** specifies the numerical base for conversion (e.g., 10 for decimal, 16 for hexadecimal). The result of the conversion is stored in **val**, and the method returns the index of the first character in the substring that was not part of the valid unsigned long, or 0 if no valid unsigned long was found. |
| `ToSizeTEx:Int( val:Size_T Var,startPos:Int=0,endPos:Int=-1,format:Int=5,base:Int=10 )` | Converts a substring of this string to a size_t. The substring is defined by the range from **startPos** to **endPos**. If **endPos** is -1, the substring extends to the end of the string. The conversion process starts at **startPos** and continues until a valid size_t is parsed or the end of the substring is reached. The **format** parameter specifies one or more of the CHARSFORMAT flags (see below), and **base** specifies the numerical base for conversion (e.g., 10 for decimal, 16 for hexadecimal). The result of the conversion is stored in **val**, and the method returns the index of the first character in the substring that was not part of the valid size_t, or 0 if no valid size_t was found. |
| `ToLongIntEx:Int( val:LongInt Var,startPos:Int=0,endPos:Int=-1,format:Int=5,base:Int=10 )` | Converts a substring of this string to a long integer. The substring is defined by the range from **startPos** to **endPos**. If **endPos** is -1, the substring extends to the end of the string. The conversion process starts at **startPos** and continues until a valid long integer is parsed or the end of the substring is reached. The **format** parameter specifies one or more of the CHARSFORMAT flags (see below), and **base** specifies the numerical base for conversion (e.g., 10 for decimal, 16 for hexadecimal). The result of the conversion is stored in **val**, and the method returns the index of the first character in the substring that was not part of the valid long integer, or 0 if no valid long integer was found. |
| `ToULongIntEx:Int( val:ULongInt Var,startPos:Int=0,endPos:Int=-1,format:Int=5,base:Int=10 )` | Converts a substring of this string to an unsigned long integer. The substring is defined by the range from **startPos** to **endPos**. If **endPos** is -1, the substring extends to the end of the string. The conversion process starts at **startPos** and continues until a valid unsigned long integer is parsed or the end of the substring is reached. The **format** parameter specifies one or more of the CHARSFORMAT flags (see below), and **base** specifies the numerical base for conversion (e.g., 10 for decimal, 16 for hexadecimal). The result of the conversion is stored in **val**, and the method returns the index of the first character in the substring that was not part of the valid unsigned long integer, or 0 if no valid unsigned long integer was found. |
Strings also provide a read-only length field.
Here is an example of using string methods:
```blitzmax
Local t:String="***** HELLO *****"
Print t.length 'return length of string: 17
Print t.Find( "HE" ) 'returns index of substring "HE": 6
Print t.Replace( "*","!" ) 'replaces all "*" with "!"
Print t.ToLower() 'coverts string to lowercase
Print ":".Join( ["Hello","World"] ) 'returns "Hello:World"
```
String also provide the following functions to help with the creation of strings:
| Function | Description |
|---|---|
| `FromInt:String( value:Int )` | Creates a string from an integer. |
| `FromUInt:String( value:UInt )` | Creates a string from an unsigned integer. |
| `FromLong:String( value:Long )` | Creates a string from a long. |
| `FromULong:String( value:ULong )` | Creates a string from an unsigned long. |
| `FromLongInt:String( value:LongInt )` | Creates a string from a long integer. |
| `FromULongInt:String( value:ULongInt )` | Creates a string from an unsigned long integer. |
| `FromSizeT:String( value:Size_T )` | Creates a string from a size_t. |
| `FromFloat:String( value:Float )` | Creates a string from a float. |
| `FromDouble:String( value:Double)` | Creates a string from a double. |
| `FromCString:String( cString:Byte Ptr )` | Creates a string from a null terminated sequence of 8 bit bytes. |
| `FromWString:String( wString:Short Ptr )` | Creates a string from a null terminated sequence of 16 bit shorts. |
| `FromUTF8String:String( utf8String:Byte Ptr )` | Creates a string from a null terminated sequence of UTF-8 characters. |
| `FromBytes:String( bytes:Byte Ptr,length )` | Creates a string from a sequence of length 8 bit bytes. |
| `FromUTF8Bytes:String( utf8String:Byte Ptr, length:Int )` | Creates a string from a sequence of **length** UTF-8 bytes. |
| `FromShorts:String( shorts:Short Ptr,length )` | Creates a string from a sequence of length 16 bit shorts. |
To call a string function, use: String.Function - for example:
```blitzmax
Print String.FromInt( 10 )
```
### CHARSFORMAT Flags
The CHARSFORMAT flags can be used to specify the expected format of the number when using the `ToDoubleEx`, `ToFloatEx`, `ToIntEx`, `ToUIntEx`, `ToLongEx`, `ToULongEx`, `ToSizeTEx`, `ToLongIntEx`, or `ToULongIntEx` methods.
| Flag | Description |
|---|---|
| `CHARSFORMAT_SCIENTIFIC` | Enables parsing of scientific notation. |
| `CHARSFORMAT_FIXED` | Enables parsing of fixed point notation. |
| `CHARSFORMAT_HEX` | Enables parsing of hexadecimal notation. |
| `CHARSFORMAT_NOINFNAN` | Do not allow Infinity or NaN. |
| `CHARSFORMAT_JSON` | Enforces JSON number format. |
| `CHARSFORMAT_JSONORINFNAN` | Parses JSON number format or Infinity or NaN. |
| `CHARSFORMAT_FORTRAN` | Allows parsing of Fortran-style numbers. |
| `CHARSFORMAT_GENERAL` | The default format, encompassing both CHARSFORMAT_FIXED and CHARSFORMAT_SCIENTIFIC. |
| `CHARSFORMAT_ALLOWLEADINGPLUS` | Allows leading plus sign. |
| `CHARSFORMAT_SKIPWHITESPACE` | Enables skipping leading whitespace. |
## String Hashes
A String hash can be used for faster string equality tests. If two strings are equal, the `HashCode()` method returns identical values for both strings.
However, because there is not a unique hash for each unique string value, it is possible for different strings to return the same hash.
By default, all static/const strings will be compiled with their hash value pre-calculated.
For dynamic strings, the hash is calculated on the first call to `HashCode()`. Subsequent calls will return the cached hash value.
In string equality tests, if both strings have a calculated hash, the hash value is used. Otherwise, the standard process of comparing
the contents of each string is performed, which involves comparing each character in turn until a difference is found.
In the following example, because the two static/const strings have hashes, the comparison will compare the hash values first, saving time, rather than having to compare the String characters.
```blitzmax
Local hello:String = "Hello"
Local help:String = "Help"
If hello <> help Then
...
End If
```
## Multiline String Blocks
A multiline string block allows you to easily create strings spanning several lines - for example:
```blitzmax
Local txt:String = """
{
"name" : "Bob"
"distance" : 150
}
"""
```
Which is the equivalent to the following string creation:
```blitzmax
Local oldtxt:String = "{~n" + ..
" ~qname~q : ~qBob~q~n" + ..
" ~distance~q : 150~n" + ..
"}"
```
As you can see, a multiline string block is more natural and less clumsy, and is more representative of the final string.
A multiline string block starts with three double-quote characters (`"""`) followed by a new line.
It ends with a new line, followed by optional whitespace, and three more double-quote characters (`"""`).
The following prints a multiline string of zero length:
```blitzmax
Print """
"""
```
You cannot put a multiline string block on a single line, nor can the contents of
the string block follow the three opening double-quotes without a new line.
The following are examples of invalid multiline strings, and produce compilation errors:
```blitzmax
Local txt:String = """ """
Local txt2:String = """"""
Local txt3:String = """
hello"""
```
A multiline string can be used anywhere a normal string would typically be used, although in some places it may make the surrounding code intentions less clear:
```blitzmax
For Local s:String = EachIn """
A
B
C
D
E
F
G
""".Split("~n")
Print s
Next
```
### Whitespace
Leading and trailing whitespace is removed from each line of a multiline string.
The whitespace defined on the line with the closing quotes denotes the common leading whitespace that will be removed from the rest of the string.
For example:
```blitzmax
Print """
""" ' <- whitespace from the start of this line defines the common indentation
```
will print:
```
```
### Line Endings
Line endings are normalized, meaning that all line endings are converted to the "line feed" (`~n` / `Chr(10)`) character.
This step is performed before escaped (`~`) characters are analyzed, allowing the use of other line ending characters within the final string.
If the line continuation character (`\`) appears at the end of a line, the usual line ending is skipped, and the following line is appended instead.
For example:
```blitzmax
Print """
One
Two \
and a half
Three
"""
```
will print:
```
One
Two and a half
Three
```
[MemFree]: ../../api/brl/brl.blitz/#memfree
[TStringMap]: ../../api/collections/collections.stringmap/tstringmap
[TMap]: ../../api/brl/brl.map/tmap