Binary strings: Difference between revisions

m
→‎{{header|FutureBasic}}: Fix typo "CFSString" -> "CFString"
m (→‎{{header|FutureBasic}}: Fix typo "CFSString" -> "CFString")
 
(81 intermediate revisions by 42 users not shown)
Line 1:
{{task|String manipulation}}
 
Many languages have powerful and useful ('''binary safe''') [[wp:String (computer science)|string]] [[wp:Comparison of programming languages (string functions)|manipulation functions]], while others don't, making it harder for these languages to accomplish some tasks.
 
This task is about creating functions to handle ''binary'' strings (strings made of arbitrary bytes, i.e. ''byte strings'' according to Wikipedia) for those languages that don't have built-in support for them. If your language of choice does have this built-in support, show a possible alternative implementation for the ''functions'' or ''abilities'' already provided by the language.
This task is about creating functions to handle ''binary'' strings (strings made of arbitrary bytes, i.e. ''byte strings'' according to Wikipedia) for those languages that don't have built-in support for them.
 
If your language of choice does have this built-in support, show a possible alternative implementation for the ''functions'' or ''abilities'' already provided by the language.
 
In particular the functions you need to create are:
* String creation and destruction (when needed and if there's no [[garbage collection]] or similar mechanism)
Line 13 ⟶ 18:
* Join strings
 
<br>
Possible contexts of use: compression algorithms (like [[LZW compression]]), L-systems (manipulation of symbols), many more.
<br><br>
=={{header|11l}}==
<syntaxhighlight lang="11l">V x = Bytes(‘abc’)
print(x[0])</syntaxhighlight>
 
{{out}}
<pre>
97
</pre>
=={{header|8086 Assembly}}==
The 8086 has built-in support for handling byte and word strings, using <code>DS:SI</code> and <code>ES:DI</code> as the source and destination pointers, respectively. String functions can either auto-increment or auto-decrement the pointers held in these registers; the '''direction flag''' determines which one takes place. (<code>CLD</code> for auto-inc, <code>STD</code> for auto-dec.)
 
===Copying strings===
This is a "deep copy," i.e. after this you will have a duplicate of the string "Hello" in two separate memory locations, not just a pointer to the original stored elsewhere.
<syntaxhighlight lang="asm">;this code assumes that both DS and ES point to the correct segments.
cld
mov si,offset TestMessage
mov di,offset EmptyRam
mov cx,5 ;length of the source string, you'll need to either know this
;ahead of time or calculate it.
rep movsb
ret
 
;there is no buffer overflow protection built into these functions so be careful!
TestMessage byte "Hello"
EmptyRam byte 0,0,0,0,0</syntaxhighlight>
 
===Checking if a particular byte exists===
<syntaxhighlight lang="asm">;this code assumes that ES points to the correct segment.
cld
mov di,offset TestMessage
mov al,'o' ;the byte we wish to check
mov cx,5 ;len(Test)
 
repnz scasb ;scan through the string and stop if a match is found.
;flags will be set accordingly
ret
 
TestMessage byte "Hello"</syntaxhighlight>
 
===Compare two strings===
<syntaxhighlight lang="asm">;this code assumes that both DS and ES point to the correct segments.
cld
mov si,offset foo
mov di,offset bar
mov cx,4 ;length of the shorter of the two.
 
repz cmpsb
; this will continue until the strings are different or CX = 0,
; whichever occurs first. If, after this, the zero flag is set and CX=0,
; the strings were the same
ret
 
foo byte "test"
bar byte "test"</syntaxhighlight>
=={{header|Ada}}==
Ada has native support for single dimensioned arrays, which provide all specified operations. String is a case of array. The array of bytes is predefined in Ada in the package System.Storage_Elements ([http://www.adaic.org/standards/05rm/html/RM-13-7-1.html LRM 13.7.1]). Storage_Element is substitute for byte.
 
<langsyntaxhighlight Adalang="ada">declare
Data : Storage_Array (1..20); -- Data created
begin
Line 33 ⟶ 94:
... Data & (1,2,3,4) ... -- The result is Data with bytes 1,2,3,4 appended
... Data (3..5) ... -- The result the substring of Data from 3 to 5
end; -- Data destructed</langsyntaxhighlight>
Storage_Array is "binary string" used for memory representation. For stream-oriented I/O communication Ada provides alternative "binary string" called Stream_Element_Array ([http://www.adaic.org/standards/05rm/html/RM-13-13-1.html LRM 13.13.1]). When dealing with octets of bits, programmers are encouraged to provide a data type of their own to ensure that the byte is exactly 8 bits length. For example:
<langsyntaxhighlight Adalang="ada">type Octet is mod 2**8;
for Octet'Size use 8;
type Octet_String is array (Positive range <>) of Octet;</langsyntaxhighlight>
Alternatively:
<langsyntaxhighlight Adalang="ada">with Interfaces; use Interfaces;
...
type Octet is new Interfaces.Unsigned_8;
type Octet_String is array (Positive range <>) of Octet;</langsyntaxhighlight>
Note that all of these types will have all operations described above.
 
=={{header|ALGOL 68}}==
{{trans|Tcl}}
Line 51 ⟶ 111:
{{works with|ALGOL 68G|Any - tested with release mk15-0.8b.fc9.i386}}
<!-- {{does not work with|ELLA ALGOL 68|Any (with appropriate job cards AND formatted transput statements removed) - tested with release 1.8.8d.fc9.i386 - ELLA has no FORMATted transput}} -->
<langsyntaxhighlight lang="algol68"># String creation #
STRING a,b,c,d,e,f,g,h,i,j,l,r;
a := "hello world";
Line 143 ⟶ 203:
 
# Extract a CHAR from a CPU word #
print(("7th byte in CPU word is: ", offset ELEM word, new line))</langsyntaxhighlight>
Output:
<pre>
Line 165 ⟶ 225:
7th byte in CPU word is: w
</pre>
=={{header|Arturo}}==
 
<syntaxhighlight lang="rebol">; creation
x: "this is a string"
y: "this is another string"
z: "this is a string"
; comparison
if x = z -> print "x is z"
; assignment
z: "now this is another string too"
; copying reference
y: z
 
; copying value
y: new z
 
; check if empty
if? empty? x -> print "empty"
else -> print "not empty"
 
; append a string
'x ++ "!"
 
print x
 
; substrings
print slice x 5 8
 
; join strings
z: x ++ y
print z
 
; replace occurrences of substring
print replace z "t" "T"</syntaxhighlight>
 
{{out}}
 
<pre>x is z
not empty
this is a string!
is a
this is a string!now this is another string too
This is a sTring!now This is anoTher sTring Too</pre>
=={{header|AWK}}==
<langsyntaxhighlight AWKlang="awk">#!/usr/bin/awk -f
 
BEGIN {
Line 202 ⟶ 308:
d=a""b""c;
printf("d=<%s>\n",d);
}</langsyntaxhighlight>
 
Output:
Line 213 ⟶ 319:
d=<123 abc @456 789>
</pre>
 
 
=={{header|BASIC}}==
 
==={{header|Applesoft BASIC}}===
<langsyntaxhighlight ApplesoftBasiclang="applesoftbasic">REM STRING CREATION AND DESTRUCTION (WHEN NEEDED AND IF THERE'S NO GARBAGE COLLECTION OR SIMILAR MECHANISM)
A$ = "STRING" : REM CREATION
A$ = "" : REM DESTRUCTION
Line 245 ⟶ 349:
 
REM JOIN STRINGS
J$ = A$ + STR$(42) + " PUDDLES " + B$ + CHR$(255) : REM USE +</langsyntaxhighlight>
 
==={{header|GW-BASIC}}===
Also works in QBASIC, QuickBASIC, VB-DOS and PDS 7.1
<syntaxhighlight lang="qbasic">
10 ' SAVE"BINSTR", A
20 ' This program does string manipulation
30 A$ = "One value" ' String creation
40 A$ = "": PRINT FRE("") ' String destruction
50 A$ = "One value": B$ = "Other value" ' String assignment
60 PRINT A$ = B$; A$ <> B$; A$ < B$; A$ > B$; A$ <= B$; A$ >= B$' String comparison
70 B$ = A$ ' String cloning and copying
80 PRINT A$ = ""' Check if a string is empty
90 A$ = A$ + "!": PRINT A$' Append a byte to a string
100 PRINT MID$(A$, 5, 5); MID$(A$, 4, 1); LEFT$(A$, 3); RIGHT$(A$, 1)' Extract a substring from a string
110 B$ = "e": WHILE INSTR(A$, B$) > 0: MID$(A$, INSTR(A$, B$), 1) = "x": WEND: PRINT A$' Replace every ocurrence of a byte in a string with another string
120 C$ = A$ + " and " + STRING$(10, "-"): PRINT C$' Join strings
130 END</syntaxhighlight>
 
 
==={{header|IS-BASIC}}===
<syntaxhighlight lang="is-basic">100 RANDOMIZE
110 REM create two strings
120 LET S$="Hello":LET T$="Bob"
130 REM choose any random character
140 LET C=(RND(127)+32)
150 REM add the character to the string
160 LET S$=S$&CHR$(C)
170 REM check if the string is empty
180 IF S$="" THEN PRINT "String is empty"
190 REM compare two strings
200 IF S$=T$ THEN PRINT "Strings are the same."
210 REM print characters 2 to 4 of a string (a substring)
220 PRINT S$(2:4)</syntaxhighlight>
 
==={{header|OxygenBasic}}===
<syntaxhighlight lang="text">
'STRING CREATION AND DESTRUCTION
string A
A = "STRING" 'CREATION
A = "" 'EMPTY
del A 'DESTRUCTION
'STRING ASSIGNMENT
string A = "STRING"
string R = "DEUX"
 
'STRING COMPARISON
print A==R : print A<>R ': print A<=R : print A>=R : print A<R : print A>R
'STRING CLONING AND COPYING
string B = A
'CHECK IF A STRING IS EMPTY
if not A then print "A is empty"
'APPEND A BYTE TO A STRING
A = A + chr(0)
A += chr(0)
'EXTRACT A SUBSTRING FROM A STRING
string S = mid(A, 2, 3)
'REPLACE EVERY OCCURRENCE OF A STRING) IN A STRING WITH ANOTHER STRING
int I=1
do
I=instr(I,S,"abc")
if not I
exit do
endif
S=left(S,I-1)+"defg"+mid(S,I+3)
I+=4
loop
'JOIN STRINGS
A="DUCKS "
string J = A str(42) " PUDDLES " R chr(255) 'CAN ALSO USE '+' OR '&' BTWEEN STRINGS
print J
</syntaxhighlight>
 
==={{header|ZX Spectrum Basic}}===
<langsyntaxhighlight lang="basic">10 REM create two strings
20 LET s$ = "Hello"
30 LET t$ = "Bob"
Line 260 ⟶ 442:
110 IF s$ = t$ THEN PRINT "Strings are the same"
120 REM print characters 2 to 4 of a string (a substring)
130 PRINT s$(2 TO 4)</langsyntaxhighlight>
 
=={{header|BBC BASIC}}==
<langsyntaxhighlight lang="bbcbasic"> A$ = CHR$(0) + CHR$(1) + CHR$(254) + CHR$(255) : REM assignment
B$ = A$ : REM clone / copy
IF A$ = B$ THEN PRINT "Strings are equal" : REM comparison
Line 278 ⟶ 459:
IF I% MID$(A$, I%, 1) = new$
UNTIL I% = 0
</syntaxhighlight>
</lang>
=={{header|BQN}}==
 
'''Based on:''' [[J]]
 
BQN characters are Unicode code points, so that it has no dedicated support for byte strings. However, strings of code points less than 256 are stored with one byte per character in CBQN, and used to represent byte strings by functions such as <code>•file.Bytes</code>.
 
* Example binary string creation
<syntaxhighlight lang="bqn"> name ← ""</syntaxhighlight>
 
* Example binary string deletion: effectively replaces the data with an integer, removing it from an accessible name.
<syntaxhighlight lang="bqn"> name ↩ 0</syntaxhighlight>
 
* Example binary string assignment
<syntaxhighlight lang="bqn"> name ← "value"</syntaxhighlight>
 
* Example binary string comparison
<syntaxhighlight lang="bqn"> name1 ≡ name2</syntaxhighlight>
 
* Example binary string cloning and copying
<syntaxhighlight lang="bqn"> name1 ← "example"
name2 ← name1</syntaxhighlight>
 
* Example check if a binary string is empty
<syntaxhighlight lang="bqn"> 0=≠string</syntaxhighlight>
 
* Example apppend a byte to a binary string
<syntaxhighlight lang="bqn"> string ← "example"
byte ← @
string ∾↩ byte</syntaxhighlight>
 
* Extract a substring from a binary string
<syntaxhighlight lang="bqn"> 3↓¯5↓"The quick brown fox runs..."</syntaxhighlight>
 
* Join strings
<syntaxhighlight lang="bqn"> "string1"∾"string2"</syntaxhighlight>
 
Note also: given an integer n, the corresponding byte value may be added to the null character <code>@</code> to get the character at that codepoint. This works due to BQN's character arithmetic.
<syntaxhighlight lang="bqn"> n + @</syntaxhighlight>
 
Thus, the binary string containing bytes with numeric values 1 0 255 can be obtained this way:
<syntaxhighlight lang="bqn">1‿0‿255 + @</syntaxhighlight>
=={{header|C}}==
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Line 418 ⟶ 639:
 
return 0;
}</langsyntaxhighlight>
 
=={{header|C sharp|C#}}==
{{works with|C sharp|3.0}}
 
<langsyntaxhighlight lang="csharp">using System;
 
class Program
Line 487 ⟶ 707:
Console.WriteLine(join);
}
}</langsyntaxhighlight>
=={{header|C++}}==
<syntaxhighlight lang="cpp">#include <iomanip>
#include <iostream>
 
using namespace std;
 
string replaceFirst(string &s, const string &target, const string &replace) {
auto pos = s.find(target);
if (pos == string::npos) return s;
return s.replace(pos, target.length(), replace);
}
 
int main() {
 
// string creation
string x = "hello world";
 
// reassign string (no garbage collection)
x = "";
 
// string assignment with a null byte
x = "ab\0";
cout << x << '\n';
cout << x.length() << '\n';
 
// string comparison
if (x == "hello") {
cout << "equal\n";
} else {
cout << "not equal\n";
}
if (x < "bc") {
cout << "x is lexigraphically less than 'bc'\n";
}
 
// string cloning
auto y = x;
cout << boolalpha << (x == y) << '\n';
cout << boolalpha << (&x == &y) << '\n';
 
// check if empty
string empty = "";
if (empty.empty()) {
cout << "String is empty\n";
}
 
// append a byte
x = "helloworld";
x += (char)83;
cout << x << '\n';
 
// substring
auto slice = x.substr(5, 5);
cout << slice << '\n';
 
// replace bytes
auto greeting = replaceFirst(x, "worldS", "");
cout << greeting << '\n';
 
// join strings
auto join = greeting + ' ' + slice;
cout << join << '\n';
 
return 0;
}</syntaxhighlight>
{{out}}
<pre>ab
2
not equal
x is lexigraphically less than 'bc'
true
false
String is empty
helloworldS
world
hello
hello world</pre>
=={{header|Common Lisp}}==
String creation (garbage collection will handle its destruction)
using the string as an atom and casting a character list to a string
<langsyntaxhighlight lang="lisp">
"string"
(coerce '(#\s #\t #\r #\i #\n #\g) 'string)
</syntaxhighlight>
</lang>
 
String assignment
<langsyntaxhighlight lang="lisp">
(defvar *string* "string")
</syntaxhighlight>
</lang>
 
comparing two string
<langsyntaxhighlight lang="lisp">
(equal "string" "string")
</syntaxhighlight>
</lang>
 
copy a string
<langsyntaxhighlight lang="lisp">
(copy-seq "string")
</syntaxhighlight>
</lang>
 
<langsyntaxhighlight lang="lisp">
(defun string-empty-p (string)
(zerop (length string)))</syntaxhighlight>
(cond
((= 0 (length string))t)
(nil)))
</lang>
 
<langsyntaxhighlight lang="lisp">
(concatenate 'string "string" "b")
</syntaxhighlight>
</lang>
 
<langsyntaxhighlight lang="lisp">
(subseq "string" 12 6)
"ring"
</syntaxhighlight>
</lang>
 
string replacement isn't covered by the ansi standard probably best to use (replace-all) or cl-ppcre
Line 533 ⟶ 825:
 
joining strings works in the same way as appending bytes
 
=={{header|Component Pascal}}==
BlackBox Component Builder
<langsyntaxhighlight lang="oberon2">
MODULE NpctBinaryString;
IMPORT StdLog,Strings;
Line 601 ⟶ 892:
END Do;
END NpctBinaryString.
</syntaxhighlight>
</lang>
Execute: ^Q NpctBinaryString.Do<br/>
Output:
Line 617 ⟶ 908:
</pre>
=={{header|D}}==
<langsyntaxhighlight lang="d">void main() /*@safe*/ {
import std.array: empty, replace;
import std.string: representation, assumeUTF;
Line 661 ⟶ 952:
// Join two strings.
ubyte[] str3 = str1 ~ str2;
}</langsyntaxhighlight>
=={{header|Delphi}}==
{{libheader| System.SysUtils}}
{{Trans|C#}}
<syntaxhighlight lang="delphi">
program Binary_strings;
 
{$APPTYPE CONSOLE}
 
uses
System.SysUtils;
 
var
x : string;
c : TArray<Byte>;
objecty,
y : string;
empty : string;
nullString : string;
whitespace,
slice,
greeting,
join : string;
begin
//string creation
x:= String.create(['1','2','3']);
x:= String.create('*',8);
x := 'hello world';
 
//# string assignment with a hex byte
x := 'ab'#10;
writeln(x);
writeln(x.Length); // 3
 
//# string comparison
if x = 'hello' then
writeln('equal')
else
writeln('not equal');
if x.CompareTo('bc') = -1 then
writeln('x is lexicographically less than "bc"');
 
//# string cloning
y := x; // string is not object is delphi (are imutables)
writeln(x = y); //same as string.equals
writeln(x.Equals(y)); //it overrides object.Equals
 
//# check if empty
// Strings can't be null (nil), just Pchar can be
// IsNullOrEmpty and IsNullOrWhiteSpace, check only for
// Empty and Whitespace respectively.
empty := '';
whitespace := ' ';
if (empty = string.Empty) and
string.IsNullOrEmpty(empty) and
string.IsNullOrWhiteSpace(empty) and
string.IsNullOrWhiteSpace(whitespace) then
writeln('Strings are empty or whitespace');
 
//# append a byte
x := 'helloworld';
x := x + Chr(83);
// x := x + #83; // the same of above line
writeln(x);
 
//# substring
slice := x.Substring(5, 5);
writeln(slice);
 
//# replace bytes
greeting := x.Replace('worldS', '');
writeln(greeting);
 
//# join strings
join := greeting + ' ' + slice;
writeln(join);
 
Readln;
end.</syntaxhighlight>
{{out}}
<pre>ab
 
3
not equal
x is lexicographically less than "bc"
TRUE
TRUE
Strings are empty or whitespace
helloworldS
world
hello
hello world</pre>
=={{header|Déjà Vu}}==
 
Déjà Vu has a <code>blob</code> type, which is much like Python 3's <code>bytearray</code>. They are used for dealing with binary data in the standard library, and works basically like a list, except it can only have integer numbers from 0 to 255 as elements, pushing and popping is not supported, and can be resized to any size in a single step.
 
<langsyntaxhighlight lang="dejavu">local :b make-blob 10 #ten bytes of initial size
set-to b 0 255
!. get-from b 0 #prints 255
Line 677 ⟶ 1,058:
!. b #prints (blob:"abc")
!. !encode!utf-8 b #prints "abc"
</syntaxhighlight>
</lang>
 
=={{header|E}}==
 
Line 687 ⟶ 1,067:
To work with binary strings we must first have a byte type; this is a place where E shows its Java roots (to be fixed).
 
<langsyntaxhighlight lang="e">? def int8 := <type:java.lang.Byte>
# value: int8</langsyntaxhighlight>
 
<ol>
<li>There are several ways to create a FlexList; perhaps the simplest is:
<langsyntaxhighlight lang="e">? def bstr := [].diverge(int8)
# value: [].diverge()
 
Line 699 ⟶ 1,079:
 
? def bstr2 := [-0x7F,0x2,0x3].diverge(int8)
# value: [-127, 2, 3].diverge()</langsyntaxhighlight>
As E is a memory-safe garbage-collected language there is no explicit destruction. It is good practice to work with immutable ConstLists when reasonable, however; especially when passing strings around.
</li><li>There is no specific assignment between FlexLists; a reference may be passed in the usual manner, or the contents of one could be copied to another as shown below.
</li><li>There is no comparison operation between FlexLists (since it would not be a stable ordering <!-- XXX cite? -->), but there is between ConstLists.
<langsyntaxhighlight lang="e">? bstr1.snapshot() < bstr2.snapshot()
# value: false</langsyntaxhighlight>
</li><li>To make an independent copy of a FlexList, simply <code>.diverge()</code> it again.
</li><li><langsyntaxhighlight lang="e">? bstr1.size().isZero()
# value: false
 
? bstr.size().isZero()
# value: true</langsyntaxhighlight>
</li><li>Appending a single element to a FlexList is done by <code>.push(<var>x</var>)</code>:
<langsyntaxhighlight lang="e">? bstr.push(0)
? bstr
# value: [0].diverge()</langsyntaxhighlight>
</li><li>Substrings, or ''runs'', are always immutable and specified as start-end indexes (as opposed to first-last or start-count). Or, one can copy an arbitrary portion of one list into another using <code>replace(<var>target range</var>, <var>source list</var>, <var>source range</var>)</code>.
<langsyntaxhighlight lang="e">? bstr1(1, 2)
# value: [2]
 
? bstr.replace(0, bstr.size(), bstr2, 1, 3)
? bstr
# value: [2, 3].diverge()</langsyntaxhighlight>
</li><li>Replacing must be written as an explicit loop; there is no built-in operation (though there is for character strings).
<langsyntaxhighlight lang="e">? for i => byte ? (byte == 2) in bstr2 { bstr2[i] := -1 }
? bstr2
# value: [-127, -1, 3].diverge()</langsyntaxhighlight>
</li><li>Two lists can be concatenated into a ConstList by <code>+</code>: <code>bstr1 + bstr2</code>. <code>append</code> appends on the end of a FlexList, and <code>replace</code> can be used to insert at the beginning or anywhere inside.
<langsyntaxhighlight lang="e">? bstr1.append(bstr2)
? bstr1
# value: [1, 2, 3, -127, 2, 3].diverge()</langsyntaxhighlight>
</li></ol>
 
=={{header|Ecstasy}}==
<syntaxhighlight lang="java">
module BinaryStrings {
@Inject Console console;
void run() {
Byte[] mutableBytes = new Byte[]; // growable and mutable string of bytes
Byte[] fixedLength = new Byte[10]; // fixed length string of bytes (all default to 0)
Byte[] literal = [0, 1, 7, 0xff]; // a "constant" string of bytes
console.print($|String creation and assignment:
| mutableBytes={mutableBytes}
| fixedLength={fixedLength}
| literal={literal}
|
);
 
console.print($|Check if a string is empty:
| mutableBytes.empty={mutableBytes.empty}
| fixedLength.empty={fixedLength.empty}
| literal.empty={literal.empty}
|
);
 
mutableBytes += 0; // add a byte (using an operator)
mutableBytes.add(1); // add a byte (using the underlying method)
mutableBytes.addAll(#07FF); // add multiple bytes (using the underlying method)
console.print($|Append a byte to a string:
| mutableBytes={mutableBytes}
|
);
 
console.print($|String comparison:
| mutableBytes==literal = {mutableBytes==literal}
| fixedLength==literal = {fixedLength==literal}
|
);
 
fixedLength = new Byte[4](i -> literal[i]); // create/copy from literal to fixedLength
val clone = fixedLength.duplicate(); // clone the array
console.print($|String cloning and copying:
| fixedLength={fixedLength}
| clone={clone}
|
);
 
console.print($|Extract a substring from a string:
| mutableBytes[1..2]={mutableBytes[1..2]}
| fixedLength[0..2]={fixedLength[0..2]}
| literal[2..3]={literal[2..3]}
|
);
 
for (Int start = 0; Int index := fixedLength.indexOf(0x01, start); start = index) {
fixedLength[index] = 0x04;
}
console.print($|Replace every occurrence of a byte in a string with another string:
| fixedLength={fixedLength}
|
);
 
for (Int start = 0; Int index := mutableBytes.indexOf(#0107, start); start = index) {
mutableBytes.replaceAll(index, #9876);
}
console.print($|Replace every occurrence of a string in a string with another string:
| mutableBytes={mutableBytes}
|
);
 
console.print($|Join strings:
| mutableBytes+fixedLength+literal={mutableBytes+fixedLength+literal}
|
);
}
}
</syntaxhighlight>
 
{{out}}
<pre>
String creation and assignment:
mutableBytes=0x
fixedLength=0x00000000000000000000
literal=0x000107FF
 
Check if a string is empty:
mutableBytes.empty=True
fixedLength.empty=False
literal.empty=False
 
Append a byte to a string:
mutableBytes=0x000107FF
 
String comparison:
mutableBytes==literal = True
fixedLength==literal = False
 
String cloning and copying:
fixedLength=0x000107FF
clone=0x000107FF
 
Extract a substring from a string:
mutableBytes[1..2]=0x0107
fixedLength[0..2]=0x000107
literal[2..3]=0x07FF
 
Replace every occurrence of a byte in a string with another string:
fixedLength=0x000407FF
 
Replace every occurrence of a string in a string with another string:
mutableBytes=0x009876FF
 
Join strings:
mutableBytes+fixedLength+literal=0x009876FF000407FF000107FF
</pre>
 
=={{header|Elixir}}==
Note: Elixir data types are immutable.
<syntaxhighlight lang="elixir"># String creation
x = "hello world"
 
# String destruction
x = nil
 
# String assignment with a null byte
x = "a\0b"
IO.inspect x #=> <<97, 0, 98>>
IO.puts String.length(x) #=> 3
 
# string comparison
if x == "hello" do
IO.puts "equal"
else
IO.puts "not equal" #=> not equal
end
y = "bc"
if x < y do
IO.puts "#{x} is lexicographically less than #{y}" #=> a b is lexicographically less than bc
end
 
# string cloning
xx = x
IO.puts x == xx #=> true (same length and content)
 
# check if empty
if x=="" do
IO.puts "is empty"
end
if String.length(x)==0 do
IO.puts "is empty"
end
 
# append a byte
IO.puts x <> "\07" #=> a b 7
IO.inspect x <> "\07" #=> <<97, 0, 98, 0, 55>>
 
# substring
IO.puts String.slice("elixir", 1..3) #=> lix
IO.puts String.slice("elixir", 2, 3) #=> ixi
 
# replace bytes
IO.puts String.replace("a,b,c", ",", "-") #=> a-b-c
 
# string interpolation
a = "abc"
n = 100
IO.puts "#{a} : #{n}" #=> abc : 100
 
# join strings
a = "hel"
b = "lo w"
c = "orld"
IO.puts a <> b <> c #=> hello world</syntaxhighlight>
=={{header|Erlang}}==
<langsyntaxhighlight lang="erlang">-module(binary_string).
-compile([export_all]).
 
Line 781 ⟶ 1,331:
replace(Rest,Value,Replacement,<< Acc/binary, Replacement >>);
replace(<<Keep,Rest/binary>>,Value,Replacement,Acc) ->
replace(Rest,Value,Replacement,<< Acc/binary, Keep >>).</langsyntaxhighlight>
{{out}}
<langsyntaxhighlight lang="erlang">215> binary_string:test().
Creation: <<0,1,1,2,3,5,8,13>>
Copy: <<0,1,1,2,3,5,8,13>>
Line 792 ⟶ 1,342:
Replacement: <<0,42,42,2,3,5,8,13>>
Append: <<0,1,1,2,3,5,8,13,21>>
Join: <<0,1,1,2,3,5,8,13,21,34,55>></langsyntaxhighlight>
 
=={{header|Factor}}==
Factor has a <code>byte-array</code> type which works exactly like other arrays, except only bytes can be stored in it. Comparisons on <code>byte-array</code>s (like comparisons on arrays) are lexicographic.
 
To convert a string to a byte-array:
<langsyntaxhighlight lang="factor">"Hello, byte-array!" utf8 encode .</langsyntaxhighlight>
<pre>
B{
Line 805 ⟶ 1,354:
</pre>
Reverse:
<langsyntaxhighlight lang="factor">B{ 147 250 150 123 } shift-jis decode .</langsyntaxhighlight>
<pre>"日本"</pre>
 
=={{header|Forth}}==
In Forth, as in Assembler, all strings are binary ie: they are simply bytes in memory. <br>
Line 813 ⟶ 1,361:
This code is an example of how to create string functions from low-level operations.
<br>
TheUsing an Indirect Threaded Forth, this code compiles to only 304 bytes on a 16 bit controller! (with labels stripped out)
Adding the 256 byte buffer it takes only 560 bytes; useable in small embedded environments.
 
<langsyntaxhighlight lang="forth">\ Rosetta Code Binary Strings Demo in Forth
\ Portions of this code are found at http://forth.sourceforge.net/mirror/toolbelt-ext/index.html
 
Line 828 ⟶ 1,376:
: STRLEN ( addr -- length) c@ ; \ alias the "character fetch" operator
 
: COUNT ( addr -- addr+1 length) \ returnsStandard theword. address+1Shown andfor the length byte on the stackexplanation
dup strlen swap 1+ swap ; \ returns the address+1 and the length byte on the stack
 
: ENDSTR ( str -- addr) \ calculate the address at the end of a string
Line 844 ⟶ 1,392:
 
: PLACE ( addr1 len addr2 -- ) \ addr1 and length, placed at addr2 as counted string
2dup 2>r 1char+ swap move 2r> c! ;
 
: STRING, ( addr len -- ) \ compile a string at the next available memory (called 'HERE')
here over 1char+ allot place ;
 
: APPEND-CHAR ( char string -- ) \ append char to string
Line 891 ⟶ 1,439:
 
: substr ( string1 start length -- strpad) \ Extract a substring of string and return an output string
strpad ="">r >r \ clearpush strpadstart,length
>r count \ pushcompute theaddr,len length
+ r> 1- /string \ pop start, subtract 1, cut string \ calc the new start addr
drop r> strpad append \ popdrop theexisting length, andpop appendnew to strpadlength
strpad ;place \ place new stack \ return the addressstring ofin strpad.
strpad ; \ return address of strpad
 
 
\ COMPARE takes the 4 inputs from the stack (addr1 len1 addr2 len2 )
Line 914 ⟶ 1,462:
comparestr 1 = ;
 
</syntaxhighlight>
</lang>
 
With the above code compiled into our system, we can test interactively
at the Forth console to see if we have satisfied the Rosetta code requirements
 
<langsyntaxhighlight lang="forth">\ Rosetta Code Binary String tasks Console Tests
 
\ 1. String creation and destruction (when needed and if there's no garbage collection or similar mechanism)
 
\ RAW Forth can manually create a binary string with the C, operator.
\ C, takes a byte off the stack and writes it into the next available memory address
\ then increments the Forth internal memory pointer by 1 byte.
\ 'binary_string' drops it's data address on the stack. Nothing more.
\ 'binary_string' drops it's address on the stack. Nothing more. (ie: pointer to the string)
 
HEX ok
Line 933 ⟶ 1,482:
 
\ test what we created using the DUMP utility
binary_string count dump
25EC:7365 01 02 03 04 05 0A 0B 0C FF 04 44 55 4D 50 00 20 ..........DUMP.
ok
 
binary_string count dump
25EC:7365 01 02 03 04 05 0A 0B 0C FF 04 44 55 4D 50 00 20 ..........DUMP.
ok
 
 
\ create static string variables using our constructor ok
\ Alternatively we can create static string variables using our constructor
string: buffer1 ok
string: buffer2 ok
Line 991 ⟶ 1,541:
string1 writestr Now is the time for all good men to come to the aid ok
buffer1 writestr Now is the time for all good men to come to the aid ok
 
 
 
Line 1,044 ⟶ 1,593:
ok
 
</syntaxhighlight>
</lang>
=={{header|FreeBASIC}}==
<syntaxhighlight lang="freebasic">
Dim As String cad, cad2
'creación de cadenas
cad = "¡Hola Mundo!"
 
'destrucción de cadenas: no es necesario debido a la recolección de basura
cad = ""
 
'clonación/copia de cadena
cad2 = cad
 
'comparación de cadenas
If cad = cad2 Then Print "Las cadenas son iguales"
 
'comprobar si está vacío
If cad = "" Then Print "Cadena vac¡a"
 
'agregar un byte
cad += Chr(33)
 
'extraer una subcadena
cad2 = Mid(cad, 1, 5)
 
'reemplazar bytes
cad2 = "­Hola mundo!"
For i As Integer = 1 To Len(cad2)
If Mid(cad2,i,1) = "l" Then
cad2 = Left(cad2,i-1) + "L" + Mid(cad2,i+1)
End If
Next
Print cad2
 
'unir cadenas
cad = "Hasta " + "pronto " + "de momento."
 
'imprimir caracteres 2 a 4 de una cadena (una subcadena)
For i As Integer = 2 To 4
Print Chr(cad[i])
Next i
Sleep
</syntaxhighlight>
 
 
 
 
=={{header|FutureBasic}}==
FB offers 255-character Pascal strings, and CFStrings — Apple's Core Foundation strings which are toll-free bridged with Objective-C's NSStrings.
Pascal strings are an array of bytes with the string length stored in byte 0.
CFStrings are immutable objects that encode a Unicode-compliant text string, represented as a sequence of UTF–16 code units. All lengths, character indexes, and ranges are expressed in terms of 16-bit platform-endian values, with index values starting at 0. The private contents of the string object are accessed via a pointer to its address. CFStrings are technically unlimited in length. While basic CFString manipulation is shown below, FB's CocoaUI offers a host of sophisticated accessor functions. Immutable CFStrings have a mutable sister, CFMutableStrings.
 
'''Pascal String example:'''
<syntaxhighlight lang="futurebasic">
// Pascal Strings (limited to 255 characters)
print "----------------------"
print "Pascal String Examples"
print "----------------------"
 
// Dimension strings and iterator
Str255 s, a
short i
 
// Create string
s = "Hello, world!"
 
// Get length of string using length byte at 0 index
print @"Length of \"Hello, world!\" is "; s[0]; @" characters."
 
// String destruction
s = ""
 
// String comparison
if s == "Hello, world!" then print "Strings are equal"
 
// Copying string
a = s
 
// Check If empty
if s == "" then print "String is empty"
 
// Append a byte
s = s + chr$(65)
 
// Extract a substring
a = mid$( s, 1, 5 ) // bytes 1 -> 5
 
// Substitute string "world" with "universe"
a = "Hello, world!"
for i = 1 to len$(a)
if ( mid$( a, i, 5 ) == "world" )
a = left$( a, i -1 ) + "universe" + mid$( a, i + 5 )
end if
next
print a
 
// Join strings
s = "See " + "you " + "later."
print s
print : print
 
HandleEvents
</syntaxhighlight>
{{output}}
<pre>
----------------------
Pascal String Examples
----------------------
Length of "Hello, world!" is 13 characters.
String is empty
Hello, universe!
See you later.
</pre>
 
'''CFString example:'''
<syntaxhighlight lang="futurebasic">
print @"----------------------"
print @" CFString Examples"
print @"----------------------"
 
// Dimension strings and iterator
CFStringRef c, b
NSUInteger j
 
// Create CFString as pointer to Core Foundation object
c = @"Hello, world!"
 
// Get length of string
print @"Length of \"Hello, world!\" is "; len(c); @" characters."
 
// String destruction
c = @""
 
// String comparison
if fn StringIsEqual( c, @"Hello, world!" ) then print @"Strings are equal"
 
// Copying string
b = c
 
// Check if empty
if len(c) == 0 then print @"String is empty"
 
// Append a byte
c = fn StringWithString( @"A" )
 
// Extract a substring
b = mid( c, 1, 5 )
 
// Substitute string "world" with "universe"
b = @"Hello, world!"
for j = 0 to len(b) - 1
if ( fn StringIsEqual( mid( b, j, 6 ), @"world!" ) )
b = fn StringWithFormat( @"%@%@", left( b, j ), @"universe!" )
exit for
end if
next
print b
 
// Join strings
c = fn StringWithFormat( @"%@%@%@", @"See ", @"you ", @"later." )
print c
 
HandleEvents
</syntaxhighlight>
{{output}}
<pre>
----------------------
CFString Examples
----------------------
Length of "Hello, world!" is 13 characters.
String is empty
Hello, universe!
See you later.
</pre>
 
=={{header|Go}}==
<langsyntaxhighlight lang="go">package main
 
import (
Line 1,131 ⟶ 1,853:
rem := append(append([]byte{}, b[:1]...), b[3:]...)
fmt.Println(string(rem))
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,145 ⟶ 1,867:
bary
</pre>
=={{header|Groovy}}==
{{trans|Java}}
<syntaxhighlight lang="groovy">import java.nio.charset.StandardCharsets
 
class MutableByteString {
private byte[] bytes
private int length
 
MutableByteString(byte... bytes) {
setInternal(bytes)
}
 
int length() {
return length
}
 
boolean isEmpty() {
return length == 0
}
 
byte get(int index) {
return bytes[check(index)]
}
 
void set(byte[] bytes) {
setInternal(bytes)
}
 
void set(int index, byte b) {
bytes[check(index)] = b
}
 
void append(byte b) {
if (length >= bytes.length) {
int len = 2 * bytes.length
if (len < 0) {
len = Integer.MAX_VALUE
}
bytes = Arrays.copyOf(bytes, len)
}
bytes[length] = b
length++
}
 
MutableByteString substring(int from, int to) {
return new MutableByteString(Arrays.copyOfRange(bytes, from, to))
}
 
void replace(byte[] from, byte[] to) {
ByteArrayOutputStream copy = new ByteArrayOutputStream()
if (from.length == 0) {
for (byte b : bytes) {
copy.write(to, 0, to.length)
copy.write(b)
}
copy.write(to, 0, to.length)
} else {
for (int i = 0; i < length; i++) {
if (regionEqualsImpl(i, from)) {
copy.write(to, 0, to.length)
i += from.length - 1
} else {
copy.write(bytes[i])
}
}
}
set(copy.toByteArray())
}
 
boolean regionEquals(int offset, MutableByteString other, int otherOffset, int len) {
if (Math.max(offset, otherOffset) + len < 0) {
return false
}
if (offset + len > length || otherOffset + len > other.length()) {
return false
}
for (int i = 0; i < len; i++) {
if (bytes[offset + i] != other.get(otherOffset + i)) {
return false
}
}
return true
}
 
String toHexString() {
char[] hex = new char[2 * length]
for (int i = 0; i < length; i++) {
hex[2 * i] = "0123456789abcdef".charAt(bytes[i] >> 4 & 0x0F)
hex[2 * i + 1] = "0123456789abcdef".charAt(bytes[i] & 0x0F)
}
return new String(hex)
}
 
String toStringUtf8() {
return new String(bytes, 0, length, StandardCharsets.UTF_8)
}
 
private void setInternal(byte[] bytes) {
this.bytes = bytes.clone()
this.length = bytes.length
}
 
private boolean regionEqualsImpl(int offset, byte[] other) {
int len = other.length
if (offset < 0 || offset + len < 0)
return false
if (offset + len > length)
return false
for (int i = 0; i < len; i++) {
if (bytes[offset + i] != other[i])
return false
}
return true
}
 
private int check(int index) {
if (index < 0 || index >= length)
throw new IndexOutOfBoundsException(String.valueOf(index))
return index
}
}</syntaxhighlight>
 
Test Code
<syntaxhighlight lang="groovy">import org.testng.Assert
import org.testng.annotations.Test
 
import java.nio.charset.StandardCharsets
 
class MutableByteStringTest {
@Test
void replaceEmpty() {
MutableByteString str = new MutableByteString("hello".getBytes(StandardCharsets.UTF_8))
str.replace([] as byte[], ['-' as char] as byte[])
 
Assert.assertEquals(str.toStringUtf8(), "-h-e-l-l-o-")
}
 
@Test
void replaceMultiple() {
MutableByteString str = new MutableByteString("hello".getBytes(StandardCharsets.UTF_8))
str.replace(['l' as char] as byte[], ['1' as char, '2' as char, '3' as char] as byte[])
 
Assert.assertEquals(str.toStringUtf8(), "he123123o")
}
 
@Test
void toHexString() {
MutableByteString str = new MutableByteString("hello".getBytes(StandardCharsets.UTF_8))
 
Assert.assertEquals(str.toHexString(), "68656c6c6f")
}
 
@Test
void append() {
MutableByteString str = new MutableByteString("hello".getBytes(StandardCharsets.UTF_8))
str.append((',' as char) as byte)
str.append((' ' as char) as byte)
str.append(('w' as char) as byte)
str.append(('o' as char) as byte)
str.append(('r' as char) as byte)
str.append(('l' as char) as byte)
str.append(('d' as char) as byte)
 
Assert.assertEquals(str.toStringUtf8(), "hello, world")
}
 
@Test
void substring() {
MutableByteString str = new MutableByteString("hello, world".getBytes(StandardCharsets.UTF_8))
 
Assert.assertEquals(str.substring(0, 5).toStringUtf8(), "hello")
Assert.assertEquals(str.substring(7, 12).toStringUtf8(), "world")
}
 
@Test
void regionEquals(){
MutableByteString str = new MutableByteString("hello".getBytes(StandardCharsets.UTF_8))
 
Assert.assertTrue(str.regionEquals(0, new MutableByteString(['h' as char] as byte[]), 0, 1))
Assert.assertFalse(str.regionEquals(0, new MutableByteString(['h' as char] as byte[]), 0, 2))
}
}</syntaxhighlight>
=={{header|Haskell}}==
Note that any of the following functions can be assigned
Line 1,157 ⟶ 2,060:
as Haskell can be somewhat intimidating to the (currently) non-
functional programmer.
<langsyntaxhighlight lang="haskell">import Text.Regex
{- The above import is needed only for the last function.
It is used there purely for readability and conciseness -}
Line 1,165 ⟶ 2,068:
Haskell would be able to figure out the type
of "world" -}
string = "world" :: String</langsyntaxhighlight>
 
<langsyntaxhighlight lang="haskell">{- Comparing two given strings and
returning a boolean result using a
simple conditional -}
Line 1,174 ⟶ 2,077:
if x == y
then True
else False</langsyntaxhighlight>
 
<langsyntaxhighlight lang="haskell">{- As strings are equivalent to lists
of characters in Haskell, test and
see if the given string is an empty list -}
Line 1,183 ⟶ 2,086:
if x == []
then True
else False</langsyntaxhighlight>
 
<langsyntaxhighlight lang="haskell">{- This is the most obvious way to
append strings, using the built-in
(++) concatenation operator
Line 1,192 ⟶ 2,095:
as typed strings -}
strAppend :: String -> String -> String
strAppend x y = x ++ y</langsyntaxhighlight>
 
<langsyntaxhighlight lang="haskell">{- Take the specified number of characters
from the given string -}
strExtract :: Int -> String -> String
strExtract x s = take x s</langsyntaxhighlight>
 
<langsyntaxhighlight lang="haskell">{- Take a certain substring, specified by
two integers, from the given string -}
strPull :: Int -> Int -> String -> String
strPull x y s = take (y-x+1) (drop x s)</langsyntaxhighlight>
 
<langsyntaxhighlight lang="haskell">{- Much thanks to brool.com for this nice
and elegant solution. Using an imported standard library
(Text.Regex), replace a given substring with another -}
strReplace :: String -> String -> String -> String
strReplace old new orig = subRegex (mkRegex old) orig new</langsyntaxhighlight>
 
=={{header|Icon}} and {{header|Unicon}}==
Icon and Unicon strings strings are variable length and unrestricted. See [[Logical_operations#Icon_and_Unicon|Logical Operations]] for ways to manipulate strings at the bit level.
<langsyntaxhighlight Iconlang="icon">s := "\x00" # strings can contain any value, even nulls
s := "abc" # create a string
s := &null # destroy a string (wellgarbage sbsnfoncollect itvalue forof garbages; set new value to collection&null)
v := s # assignment
s == t # expression s equals t
Line 1,225 ⟶ 2,127:
t := s[2+:3] # t is set to position 2 for 3 characters
s := replace(s,s2,s3) # IPL replace function
s := s1 || s2 # concatenation (joining) of strings</langsyntaxhighlight>
 
The {{libheader|Icon Programming Library}} provides the procedure [http://www.cs.arizona.edu/icon/library/src/procs/strings.icn replace in strings]
<langsyntaxhighlight Iconlang="icon">procedure replace(s1, s2, s3) #: string replacement
local result, i
 
Line 1,243 ⟶ 2,145:
}
 
end</langsyntaxhighlight>
 
=={{header|J}}==
J's literal data type supports arbitrary binary data (strings are binary strings by default). J's semantics are pass by value (with garbage collection) with a minor exception (mapped files).
 
* Example binary string creation
<langsyntaxhighlight lang="j"> name=: ''</langsyntaxhighlight>
 
* Example binary string deletion (removing all references to a string allows it to be deleted, in this case we give the name a numeric value to replace its prior string value):
<langsyntaxhighlight lang="j"> name=: 0</langsyntaxhighlight>
 
* Example binary string assignment
<langsyntaxhighlight lang="j"> name=: 'value'</langsyntaxhighlight>
 
* Example binary string comparison
<syntaxhighlight lang ="j"> name1 -: name2</langsyntaxhighlight>
 
* Example binary string cloning and copying
<langsyntaxhighlight lang="j"> name1=: 'example'
name2=: name1</langsyntaxhighlight>
 
Though, technically, its the internal reference which is cloned, not the internal representation of the value. But operations which modify strings are copy on write, so this distinction is not visible without going outside the language.
 
* Example check if a binary string is empty
<langsyntaxhighlight lang="j"> 0=#string</langsyntaxhighlight>
 
* Example apppend a byte to a binary string
<langsyntaxhighlight lang="j"> string=: 'example'
byte=: DEL
string=: string,byte</langsyntaxhighlight>
 
* Extract a substring from a binary string
<langsyntaxhighlight lang="j"> 3{.5}.'The quick brown fox runs...'</langsyntaxhighlight>
 
* Replace every occurrence of a byte (or a string) in a string with another string
<langsyntaxhighlight lang="j">require 'strings'
'The quick brown fox runs...' rplc ' ';' !!! '</langsyntaxhighlight>
 
* Join strings
<syntaxhighlight lang ="j"> 'string1','string2'</langsyntaxhighlight>
 
Note also: given an integer n, the corresponding byte value may be obtained by indexing into <code>a.</code> which is the ordered array of all bytes.:
<syntaxhighlight lang ="j"> n{a.</langsyntaxhighlight>
 
Thus, the binary string containing bytes with numeric values 1 0 255 can be obtained this way:
<syntaxhighlight lang ="j">1 0 255{a.</langsyntaxhighlight>
=={{header|Java}}==
 
<syntaxhighlight lang="java">import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
 
public class MutableByteString {
 
private byte[] bytes;
private int length;
 
public MutableByteString(byte... bytes) {
setInternal(bytes);
}
 
public int length() {
return length;
}
 
public boolean isEmpty() {
return length == 0;
}
 
public byte get(int index) {
return bytes[check(index)];
}
 
public void set(byte[] bytes) {
setInternal(bytes);
}
 
public void set(int index, byte b) {
bytes[check(index)] = b;
}
 
public void append(byte b) {
if (length >= bytes.length) {
int len = 2 * bytes.length;
if (len < 0)
len = Integer.MAX_VALUE;
bytes = Arrays.copyOf(bytes, len);
}
bytes[length] = b;
length++;
}
 
public MutableByteString substring(int from, int to) {
return new MutableByteString(Arrays.copyOfRange(bytes, from, to));
}
 
public void replace(byte[] from, byte[] to) {
ByteArrayOutputStream copy = new ByteArrayOutputStream();
if (from.length == 0) {
for (byte b : bytes) {
copy.write(to, 0, to.length);
copy.write(b);
}
copy.write(to, 0, to.length);
} else {
for (int i = 0; i < length; i++) {
if (regionEquals(i, from)) {
copy.write(to, 0, to.length);
i += from.length - 1;
} else {
copy.write(bytes[i]);
}
}
}
set(copy.toByteArray());
}
 
public boolean regionEquals(int offset, MutableByteString other, int otherOffset, int len) {
if (Math.max(offset, otherOffset) + len < 0)
return false;
if (offset + len > length || otherOffset + len > other.length())
return false;
for (int i = 0; i < len; i++) {
if (bytes[offset + i] != other.get(otherOffset + i))
return false;
}
return true;
}
 
public String toHexString() {
char[] hex = new char[2 * length];
for (int i = 0; i < length; i++) {
hex[2 * i] = "0123456789abcdef".charAt(bytes[i] >> 4 & 0x0F);
hex[2 * i + 1] = "0123456789abcdef".charAt(bytes[i] & 0x0F);
}
return new String(hex);
}
 
public String toStringUtf8() {
return new String(bytes, 0, length, StandardCharsets.UTF_8);
}
 
private void setInternal(byte[] bytes) {
this.bytes = bytes.clone();
this.length = bytes.length;
}
 
private boolean regionEquals(int offset, byte[] other) {
int len = other.length;
if (offset < 0 || offset + len < 0)
return false;
if (offset + len > length)
return false;
for (int i = 0; i < len; i++) {
if (bytes[offset + i] != other[i])
return false;
}
return true;
}
 
private int check(int index) {
if (index < 0 || index >= length)
throw new IndexOutOfBoundsException(String.valueOf(index));
return index;
}
}</syntaxhighlight>
 
Test code:
 
<syntaxhighlight lang="java">import static org.hamcrest.CoreMatchers.is;
 
import java.nio.charset.StandardCharsets;
import org.junit.Assert;
import org.junit.Test;
 
public class MutableByteStringTest {
 
@Test
public void testReplaceEmpty() {
MutableByteString str = new MutableByteString("hello".getBytes(StandardCharsets.UTF_8));
str.replace(new byte[]{}, new byte[]{'-'});
 
Assert.assertThat(str.toStringUtf8(), is("-h-e-l-l-o-"));
}
 
@Test
public void testReplaceMultiple() {
MutableByteString str = new MutableByteString("hello".getBytes(StandardCharsets.UTF_8));
str.replace(new byte[]{'l'}, new byte[]{'1', '2', '3'});
 
Assert.assertThat(str.toStringUtf8(), is("he123123o"));
}
 
@Test
public void testToHexString() {
MutableByteString str = new MutableByteString("hello".getBytes(StandardCharsets.UTF_8));
 
Assert.assertThat(str.toHexString(), is("68656c6c6f"));
}
 
@Test
public void testAppend() {
MutableByteString str = new MutableByteString("hello".getBytes(StandardCharsets.UTF_8));
str.append((byte) ',');
str.append((byte) ' ');
str.append((byte) 'w');
str.append((byte) 'o');
str.append((byte) 'r');
str.append((byte) 'l');
str.append((byte) 'd');
 
Assert.assertThat(str.toStringUtf8(), is("hello, world"));
}
@Test
public void testSubstring() {
MutableByteString str = new MutableByteString("hello, world".getBytes(StandardCharsets.UTF_8));
 
Assert.assertThat(str.substring(0, 5).toStringUtf8(), is("hello"));
Assert.assertThat(str.substring(7, 12).toStringUtf8(), is("world"));
}
 
@Test
public void testRegionEquals() {
MutableByteString str = new MutableByteString("hello".getBytes(StandardCharsets.UTF_8));
 
Assert.assertThat(str.regionEquals(0, new MutableByteString(new byte[]{'h'}), 0, 1), is(true));
Assert.assertThat(str.regionEquals(0, new MutableByteString(new byte[]{'h'}), 0, 2), is(false));
}
}</syntaxhighlight>
=={{header|JavaScript}}==
 
JavaScript has native support for binary strings. All strings are "binary" and they're not zero terminated; however to be more exact you can't really see the bytes on the string, strings go from Unicode 0 to Unicode FFFF
<langsyntaxhighlight JavaScriptlang="javascript">//String creation
var str='';
//or
Line 1,346 ⟶ 2,429:
[str," ",str3].join(" "/*this is the character that will glue the strings*/)//we can join an array of strings
str3+str4;
str.concat('\n',str4); //concantenate them</langsyntaxhighlight>
 
=={{header|jq}}==
 
jq's strings are JSON strings and so cannot be safely used as "binary strings" in the sense of this article. The most convenient way to store a string of bytes in jq is as a jq array of integers, it being understood that jq itself does **not** provide a mechanism for guaranteeing that all the elements of a particular array are integers in the expected range.
 
It is appropriate therefore to introduce a filter for verifying that an entity is an array of integers in the appropriate range:<langsyntaxhighlight lang="jq"># If the input is a valid representation of a binary string
# then pass it along:
def check_binary:
Line 1,361 ⟶ 2,443:
and 0 <= . and . <= 255) then $a
else error("\(.) is an invalid representation of a byte")
end );</langsyntaxhighlight>
Examples
<langsyntaxhighlight lang="jq">## Creation of an entity representing an empty binary string
 
[]
Line 1,433 ⟶ 2,515:
reduce .[] as $byte ([];
if $byte == x then . + a else . + [$byte] end)
</syntaxhighlight>
</lang>
=={{header|Julia}}==
{{trans|MATLAB}}
<syntaxhighlight lang="julia">
# String assignment. Creation and garbage collection are automatic.
a = "123\x00 abc " # strings can contain bytes that are not printable in the local font
b = "456" * '\x09'
c = "789"
println(a)
println(b)
println(c)
 
# string comparison
println("(a == b) is $(a == b)")
# String copying.
A = a
B = b
C = c
println(A)
println(B)
println(C)
# check if string is empty
if length(a) == 0
println("string a is empty")
else
println("string a is not empty")
end
 
# append a byte (actually this is a Char in Julia, and may also be up to 32 bit Unicode) to a string
a= a * '\x64'
println(a)
# extract a substring from string
e = a[1:6]
println(e)
# repeat strings with ^
b4 = b ^ 4
println(b4)
# Replace every occurrence of a string in another string with third string
r = replace(b4, "456" => "xyz")
println(r)
 
# join strings with *
d = a * b * c
println(d)
</syntaxhighlight>
{{output}}<pre>
123 abc
456
789
(a == b) is false
123 abc
456
789
string a is not empty
123 abc d
123 a
456 456 456 456
xyz xyz xyz xyz
123 abc d456 789
</pre>
=={{header|Kotlin}}==
Strings in Kotlin are sequences of 16-bit unicode characters and have a lot of functions built-in, including all those required by this task.
 
To do something different and consistent with the task, I've therefore implemented a simple ByteString class as a sequence of 8-bit signed bytes (Kotlin doesn't yet have an unsigned byte type) using the ISO 8859-1 encoding which, of course, represents the first 256 unicode characters. It's not possible to create user-defined literals in Kotlin and so ByteStrings need to be converted to 'ordinary' Strings to display them as such.
 
The implementation is not intended to be particularly efficient as I've sometimes delegated to the corresponding String class functions in the interests of both simplicity and brevity. Moreover, when Java 9's 'compact strings' feature is implemented, it won't even save memory as Strings which don't contain characters with code-points above 255 are apparently going to be flagged and stored internally as arrays of single bytes by the JVM, not arrays of 2 byte characters as at present.
<syntaxhighlight lang="scala">class ByteString(private val bytes: ByteArray) : Comparable<ByteString> {
val length get() = bytes.size
 
fun isEmpty() = bytes.isEmpty()
 
operator fun plus(other: ByteString): ByteString = ByteString(bytes + other.bytes)
 
operator fun plus(byte: Byte) = ByteString(bytes + byte)
 
operator fun get(index: Int): Byte {
require (index in 0 until length)
return bytes[index]
}
 
fun toByteArray() = bytes
 
fun copy() = ByteString(bytes.copyOf())
 
override fun compareTo(other: ByteString) = this.toString().compareTo(other.toString())
 
override fun equals(other: Any?): Boolean {
if (other == null || other !is ByteString) return false
return compareTo(other) == 0
}
 
override fun hashCode() = this.toString().hashCode()
 
fun substring(startIndex: Int) = ByteString(bytes.sliceArray(startIndex until length))
 
fun substring(startIndex: Int, endIndex: Int) =
ByteString(bytes.sliceArray(startIndex until endIndex))
 
fun replace(oldByte: Byte, newByte: Byte): ByteString {
val ba = ByteArray(length) { if (bytes[it] == oldByte) newByte else bytes[it] }
return ByteString(ba)
}
 
fun replace(oldValue: ByteString, newValue: ByteString) =
this.toString().replace(oldValue.toString(), newValue.toString()).toByteString()
 
override fun toString(): String {
val chars = CharArray(length)
for (i in 0 until length) {
chars[i] = when (bytes[i]) {
in 0..127 -> bytes[i].toChar()
else -> (256 + bytes[i]).toChar()
}
}
return chars.joinToString("")
}
}
 
fun String.toByteString(): ByteString {
val bytes = ByteArray(this.length)
for (i in 0 until this.length) {
bytes[i] = when (this[i].toInt()) {
in 0..127 -> this[i].toByte()
in 128..255 -> (this[i] - 256).toByte()
else -> '?'.toByte() // say
}
}
return ByteString(bytes)
}
 
/* property to be used as an abbreviation for String.toByteString() */
val String.bs get() = this.toByteString()
 
fun main(args: Array<String>) {
val ba = byteArrayOf(65, 66, 67)
val ba2 = byteArrayOf(68, 69, 70)
val bs = ByteString(ba)
val bs2 = ByteString(ba2)
val bs3 = bs + bs2
val bs4 = "GHI£€".toByteString()
println("The length of $bs is ${bs.length}")
println("$bs + $bs2 = $bs3")
println("$bs + D = ${bs + 68}")
println("$bs == ABC is ${bs == bs.copy()}")
println("$bs != ABC is ${bs != bs.copy()}")
println("$bs >= $bs2 is ${bs > bs2}")
println("$bs <= $bs2 is ${bs < bs2}")
println("$bs is ${if (bs.isEmpty()) "empty" else "not empty"}")
println("ABC[1] = ${bs[1].toChar()}")
println("ABC as a byte array is ${bs.toByteArray().contentToString()}")
println("ABCDEF(1..5) = ${bs3.substring(1)}")
println("ABCDEF(2..4) = ${bs3.substring(2,5)}")
println("ABCDEF with C replaced by G is ${bs3.replace(67, 71)}")
println("ABCDEF with CD replaced by GH is ${bs3.replace("CD".bs, "GH".bs)}")
println("GHI£€ as a ByteString is $bs4")
}</syntaxhighlight>
 
{{out}}
<pre>
The length of ABC is 3
ABC + DEF = ABCDEF
ABC + D = ABCD
ABC == ABC is true
ABC != ABC is false
ABC >= DEF is false
ABC <= DEF is true
ABC is not empty
ABC[1] = B
ABC as a byte array is [65, 66, 67]
ABCDEF(1..5) = BCDEF
ABCDEF(2..4) = CDE
ABCDEF with C replaced by G is ABGDEF
ABCDEF with CD replaced by GH is ABGHEF
GHI£€ as a ByteString is GHI£?
</pre>
=={{header|Liberty BASIC}}==
Liberty BASIC's strings are native byte strings. They can contain any byte sequence. They are not zero-terminated. They can be huge in size.
<syntaxhighlight lang="lb">
<lang lb>
'string creation
s$ = "Hello, world!"
Line 1,471 ⟶ 2,731:
'join strings
s$ = "Good" + "bye" + " for now."
</syntaxhighlight>
</lang>
=={{header|Lingo}}==
<syntaxhighlight lang="lingo">-- String creation and destruction
foo = "Hello world!" -- created by assignment; destruction via garbage collection
 
-- Strings are binary safe
put numtochar(0) into char 6 of foo
put chartonum(foo.char[6])
-- 0
put str.char[7..foo.length]
-- "world!"
 
-- String cloning and copying
bar = foo -- copies foo contents to bar
 
-- String comparison
put (foo=bar) -- TRUE
put (foo<>bar) -- FALSE
 
-- Check if a string is empty
put (foo=EMPTY)
put (foo="")
put (foo.length=0)
 
-- Append a byte to a string
put "X" after foo
put chartonum(88) after foo
 
-- Extract a substring from a string
put foo.char[3..5]
 
-- Replace every occurrence of a byte (or a string) in a string with another string
 
----------------------------------------
-- Replace in string
-- @param {string} stringToFind
-- @param {string} stringToInsert
-- @param {string} input
-- @return {string}
----------------------------------------
on replaceAll (stringToFind, stringToInsert, input)
output = ""
findLen = stringToFind.length - 1
repeat while TRUE
currOffset = offset(stringToFind, input)
if currOffset=0 then exit repeat
put input.char[1..currOffset] after output
delete the last char of output
put stringToInsert after output
delete input.char[1..(currOffset + findLen)]
end repeat
put input after output
return output
end
 
put replaceAll("o", "X", foo)
 
-- Join strings (4x the same result)
foo = "Hello " & "world!"
foo = "Hello" & numtochar(32) & "world!"
foo = "Hello" & SPACE & "world!"
foo = "Hello" && "world!"</syntaxhighlight>
=={{header|Lua}}==
<langsyntaxhighlight lang="lua">foo = 'foo' -- Ducktyping foo to be string 'foo'
bar = 'bar'
assert (foo == "foo") -- Comparing string var to string literal
Line 1,504 ⟶ 2,824:
print (str)
 
str = foo .. bar -- Strings concatenate with .. operator</langsyntaxhighlight>
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<langsyntaxhighlight Mathematicalang="mathematica">(* String creation and destruction *) BinaryString = {}; BinaryString = . ;
(* String assignment *) BinaryString1 = {12,56,82,65} , BinaryString2 = {83,12,56,65}
-> {12,56,82,65}
Line 1,525 ⟶ 2,844:
-> {12,56,82,65,33,44}
(* Join strings *) BinaryString4 = Join[BinaryString1 , BinaryString2]
-> {12,56,82,65,83,12,56,65}</langsyntaxhighlight>
 
=={{header|MATLAB}} / {{header|Octave}}==
<syntaxhighlight lang="matlab">
<lang Matlab>
a=['123',0,' abc '];
b=['456',9];
Line 1,565 ⟶ 2,883:
d=[a,b,c];
disp(d);
</syntaxhighlight>
</lang>
Output:
<pre>
Line 1,581 ⟶ 2,899:
123 abc @456 789
</pre>
 
=={{header|Nim}}==
<langsyntaxhighlight lang="nim">var # creation
x = "this is a string"
y = "this is another string"
Line 1,599 ⟶ 2,916:
 
echo x[5..8] # substring
echo x[8 .. -^1] # substring
 
z = x & y # join strings
Line 1,605 ⟶ 2,922:
import strutils
 
echo z.replace('t', 'T') # replace occurences of t with T</langsyntaxhighlight>
 
=={{header|OCaml}}==
 
Line 1,612 ⟶ 2,928:
 
<code>String.create n</code> returns a fresh string of length n, which initially contains arbitrary characters:
<langsyntaxhighlight lang="ocaml"># String.create 10 ;;
- : string = "\000\023\000\000\001\000\000\000\000\000"</langsyntaxhighlight>
 
No destruction, OCaml features a garbage collector.
Line 1,620 ⟶ 2,936:
 
* String assignment
<langsyntaxhighlight lang="ocaml"># let str = "some text" ;;
val str : string = "some text"
 
(* modifying a character, OCaml strings are mutable *)
# str.[0] <- 'S' ;;
- : unit = ()</langsyntaxhighlight>
 
* String comparison
<langsyntaxhighlight lang="ocaml"># str = "Some text" ;;
- : bool = true
 
# "Hello" > "Ciao" ;;
- : bool = true</langsyntaxhighlight>
 
* String cloning and copying
<langsyntaxhighlight lang="ocaml"># String.copy str ;;
- : string = "Some text"</langsyntaxhighlight>
 
* Check if a string is empty
<langsyntaxhighlight lang="ocaml"># let string_is_empty s = (s = "") ;;
val string_is_empty : string -> bool = <fun>
 
Line 1,646 ⟶ 2,962:
 
# string_is_empty "" ;;
- : bool = true</langsyntaxhighlight>
 
* Append a byte to a string
Line 1,655 ⟶ 2,971:
a byte and return the result as a new string
 
<langsyntaxhighlight lang="ocaml"># str ^ "!" ;;
- : string = "Some text!"</langsyntaxhighlight>
 
But OCaml has a module named Buffer for string buffers.
This module implements string buffers that automatically expand as necessary. It provides accumulative concatenation of strings in quasi-linear time (instead of quadratic time when strings are concatenated pairwise).
 
<syntaxhighlight lang ="ocaml">Buffer.add_char str c</langsyntaxhighlight>
 
* Extract a substring from a string
<langsyntaxhighlight lang="ocaml"># String.sub str 5 4 ;;
- : string = "text"</langsyntaxhighlight>
 
* Replace every occurrence of a byte (or a string) in a string with another string
using the '''Str''' module
<langsyntaxhighlight lang="ocaml"># #load "str.cma";;
# let replace str occ by =
Str.global_replace (Str.regexp_string occ) by str
Line 1,675 ⟶ 2,991:
val replace : string -> string -> string -> string = <fun>
# replace "The white dog let out a single, loud bark." "white" "black" ;;
- : string = "The black dog let out a single, loud bark."</langsyntaxhighlight>
 
* Join strings
<langsyntaxhighlight lang="ocaml"># "Now just remind me" ^ " how the horse moves again?" ;;
- : string = "Now just remind me how the horse moves again?"</langsyntaxhighlight>
 
=={{header|PARI/GP}}==
This code accepts arbitrary characters, but you can use <code>Strchr</code> to display ASCII strings.
<langsyntaxhighlight lang="parigp">cmp_str(u,v)=u==v
copy_str(v)=v \\ Creates a copy, not a pointer
append_str(v,n)=concat(v,n)
Line 1,696 ⟶ 3,011:
u[8..12]
replace_str(u,108,[121])
concat(v,w)</langsyntaxhighlight>
{{out}}
<pre>%1 = 0
Line 1,705 ⟶ 3,020:
%6 = [72, 101, 121, 121, 111, 44, 32, 119, 111, 114, 121, 100]
%7 = []</pre>
 
=={{header|Pascal}}==
Pascal's original strings were limited to 255 characters. Most implementations had the string length in byte 0. Extension exist for longer strings as well as C compatible string terminated by null. See Examples below
<langsyntaxhighlight lang="pascal">const
greeting = 'Hello';
var
Line 1,733 ⟶ 3,047:
{ Join strings}
s3 := greeting + ' and how are you, ' + s1 + '?';
end.</langsyntaxhighlight>
=={{header|Perl}}==
Effective string manipulation has been a part of Perl since the beginning. Simple stuff is simply done, but modern Perl also supports Unicode, and tools like <code>pack/unpack</code> let you operate on strings below the level of bytes.
<syntaxhighlight lang="perl">$s = undef;
say 'Nothing to see here' if ! defined $s; # 'Nothing to see here'
say $s = ''; # ''
say 'Empty string' if $s eq ''; # 'Empty string'
say $s = 'be'; # 'be'
say $t = $s; # 'be'
say 'Same' if $t eq $s; # 'Same'
say $t = $t .'e' # 'bee'
say $t .= 'keeper'; # 'beekeeper'
$t =~ s/ee/ook/; say $t; # 'bookkeeper'
say $u = substr $t, 2, 2; # 'ok'
say 'Oklahoma' . ' is ' . uc $u; # 'Oklahoma is OK'</syntaxhighlight>
=={{header|Phix}}==
The native string type in Phix can be used to store raw binary data and supports all of the operations mentioned in this task.
Strings are reference counted, and mutable with copy-on-write semantics. Memory is managed automatically and very efficiently, strings can easily be a billion characters long (on 32-bit, the precise limit is in fact 1,610,612,711 characters, available memory and performance impacts aside) and have a null terminator for C compatibility, but can contain embedded nulls as well.
Note that attempting to set an element (character/byte) to a value outside the range 0..255 will result in automatic expansion to dword-(or qword-)sequence, and can result in a run-time type check.
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"abc"</span>
<span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">x"ef bb bf"</span> <span style="color: #000080;font-style:italic;">-- explicit binary string (the utf8 BOM)</span>
<span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">3</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">'z'</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">=</span><span style="color: #008000;">"\#EF\0z"</span> <span style="color: #008080;">then</span> <span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"ok\n"</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span>
<span style="color: #000000;">t</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"xy"</span> <span style="color: #000080;font-style:italic;">-- s remains unaltered</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">t</span> <span style="color: #000080;font-style:italic;">-- "xyz"</span>
<span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"food"</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">t</span>
<span style="color: #000000;">t</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">..</span><span style="color: #000000;">3</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">'e'</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">t</span> <span style="color: #000080;font-style:italic;">-- "feed"</span>
<span style="color: #000000;">t</span><span style="color: #0000FF;">[</span><span style="color: #000000;">3</span><span style="color: #0000FF;">..</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"ast"</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">t</span> <span style="color: #000080;font-style:italic;">-- "feasted"</span>
<span style="color: #000000;">t</span><span style="color: #0000FF;">[</span><span style="color: #000000;">3</span><span style="color: #0000FF;">..-</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">t</span> <span style="color: #000080;font-style:italic;">-- "fed"</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"t is empty\n"</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">t</span><span style="color: #0000FF;">!=</span><span style="color: #008000;">""</span> <span style="color: #008080;">then</span> <span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"t is not empty\n"</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"be"</span>
<span style="color: #000000;">t</span> <span style="color: #0000FF;">&=</span> <span style="color: #008000;">'t'</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">t</span> <span style="color: #000080;font-style:italic;">-- bet</span>
<span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">'a'</span><span style="color: #0000FF;">&</span><span style="color: #000000;">t</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">t</span> <span style="color: #000080;font-style:italic;">-- abet</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">t</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">..</span><span style="color: #000000;">3</span><span style="color: #0000FF;">]</span> <span style="color: #000080;font-style:italic;">-- be</span>
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">substitute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"be"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"bbo"</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- abbot</span>
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">substitute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"be"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"dep"</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- adept</span>
<span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">substitute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"be"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"dep"</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- to actually modify t</span>
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">({</span><span style="color: #008000;">"abc"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"def"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"ghi"</span><span style="color: #0000FF;">})</span> <span style="color: #000080;font-style:italic;">-- "abc def ghi"</span>
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">({</span><span style="color: #008000;">"abc"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"def"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"ghi"</span><span style="color: #0000FF;">},</span><span style="color: #008000;">""</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- "abcdefghi"</span>
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">({</span><span style="color: #008000;">"abc"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"def"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"ghi"</span><span style="color: #0000FF;">},</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- "abc\ndef\nghi"</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
ok
"xyz"
"food"
"feed"
"feasted"
"fed"
t is not empty
"bet"
"abet"
"be"
"abbot"
"adept"
"abc def ghi"
"abcdefghi"
"abc\ndef\nghi"
</pre>
=={{header|Picat}}==
Strings in Picat are lists of characters.
<syntaxhighlight lang="picat">main => % - String assignment
S1 = "binary_string",
println(s1=S1),
 
% Picat has re-assignments (:=/2) as well,
=={{header|Perl 6}}==
S1 := "another string",
println(s1=S1),
 
% - String comparison
<lang perl6># Perl 6 is perfectly fine with NUL *characters* in strings:
if S1 == "another string" then
println(same)
else
println(not_same)
end,
% - String cloning and copying
S2 = S1,
println(s2=S2),
S3 = copy_term(S1), % for strings it's the same as =/2
println(s3=S3),
% - Check if a string is empty
if S3 == "" then
println(is_empty)
else
println(not_empty)
end,
 
% - Append a byte to a string
my Str $s = 'nema' ~ 0.chr ~ 'problema!';
S3 := S3 ++ "s",
say $s;
println(s3=S3),
% - Extract a substring from a string
println(substring=S3[5..7]),
println(slice=slice(S1,5,7)),
println(slice=slice(S1,5)),
 
% - Replace every occurrence of a byte (or a string) in a string with another string
# However, Perl 6 makes a clear distinction between strings
S4 = replace(S3,'s','x'),
# (i.e. sequences of characters), like your name, or …
println(s4=S4),
my Str $str = "My God, it's full of chars!";
# … and sequences of bytes (called Bufs), for example a PNG image, or …
my Buf $buf = Buf.new(255, 0, 1, 2, 3);
say $buf;
 
% - Join strings
# Strs can be encoded into Bufs …
S5 = S1 ++ " " ++ S2,
my Buf $this = 'foo'.encode('ascii');
println(s5=S5),
# … and Bufs can be decoded into Strs …
my Str $that = $this.decode('ascii');
 
% using append/4
# So it's all there. Nevertheless, let's solve this task explicitly
append(S1," ", S2,S6),
# in order to see some nice language features:
println(s6=S6),
 
% find positions of substrings
# We define a class …
println(find=findall([From,To],find(S5,"str",From,To))),
class ByteStr {
# … that keeps an array of bytes, and we delegate some
# straight-forward stuff directly to this attribute:
# (Note: "has byte @.bytes" would be nicer, but that is
# not yet implemented in rakudo or niecza.)
has Int @.bytes handles(< Bool elems gist push >);
 
% split a string
# A handful of methods …
println(split=split(S1," st"))</syntaxhighlight>
method clone() {
self.new(:@.bytes);
}
 
{{out}}
method substr(Int $pos, Int $length) {
<pre>s1 = binary_string
self.new(:bytes(@.bytes[$pos .. $pos + $length - 1]));
s1 = another string
}
same
s2 = another string
s3 = another string
not_empty
s3 = another strings
substring = her
slice = her
slice = her string
s4 = another xtringx
s5 = another string another string
s6 = another string another string
find = [[9,11],[24,26]]
split = [ano,her,ring]</pre>
 
Since strings are lists of characters, all list functions/procedures are supported including the non-deterministic (backtrackable) <code>member/2</code>, <code>append/3-4</code>, <code>select/3</code> as well as list comprehensions. Some examples:
method replace(*@substitutions) {
<syntaxhighlight lang="picat">main =>
my %h = @substitutions;
println(member=findall(C,(member(C,S1), C @< 'l') )),
@.bytes.=map: { %h{$_} // $_ }
}
}
 
% find substrings using append/3
# A couple of operators for our new type:
S = "string",
multi infix:<cmp>(ByteStr $x, ByteStr $y) { $x.bytes cmp $y.bytes }
println(append=findall([A,B],append(A,B,S))),
multi infix:<~> (ByteStr $x, ByteStr $y) { ByteStr.new(:bytes($x.bytes, $y.bytes)) }
% split around "r"
println(append=findall([A,B],append(A,"r",B,S))),
 
% select a character and returns the list without that character
# create some byte strings (destruction not needed due to garbage collection)
println(select=findall([C,NewS],select(C,S,NewS))),
my ByteStr $b0 = ByteStr.new;
my ByteStr $b1 = ByteStr.new(:bytes( 'foo'.ords, 0, 10, 'bar'.ords ));
 
% list comprehension
# assignment ($b1 and $b2 contain the same ByteStr object afterwards):
println(list_comprehension=[ C : C in S5, membchk(C,"aeiou")]),
my ByteStr $b2 = $b1;
% sort and remove duplicates
 
println(sort_remove_dups=sort_remove_dups(S5)).</syntaxhighlight>
# comparing:
say 'b0 cmp b1 = ', $b0 cmp $b1;
say 'b1 cmp b2 = ', $b1 cmp $b2;
 
# cloning:
my $clone = $b1.clone;
$b1.replace('o'.ord => 0);
say 'b1 = ', $b1;
say 'b2 = ', $b2;
say 'clone = ', $clone;
 
# to check for (non-)emptiness we evaluate the ByteStr in boolean context:
say 'b0 is ', $b0 ?? 'not empty' !! 'empty';
say 'b1 is ', $b1 ?? 'not empty' !! 'empty';
 
# appending a byte:
$b1.push: 123;
 
# extracting a substring:
my $sub = $b1.substr(2, 4);
say 'sub = ', $sub;
 
# replacing a byte:
$b2.replace(102 => 103);
say $b2;
 
# joining:
my ByteStr $b3 = $b1 ~ $sub;
say 'joined = ', $b3;</lang>
 
{{out}}
<pre>member = ahe ig
Note: The ␀ represents a NUL byte.
append = [[[],string],[s,tring],[st,ring],[str,ing],[stri,ng],[strin,g],[string,[]]]
<pre>nema␀problema!
append = [[st,ing]]
Buf:0x<ff 00 01 02 03>
select = [[s,tring],[t,sring],[r,sting],[i,strng],[n,strig],[g,strin]]
b0 cmp b1 = Increase
list_comprehension = aoeiaoei
b1 cmp b2 = Same
sort_remove_dups = aeghinorst</pre>
b1 = 102 0 0 0 10 98 97 114
b2 = 102 0 0 0 10 98 97 114
clone = 102 111 111 0 10 98 97 114
b0 is empty
b1 is not empty
sub = 0 0 10 98
103 0 0 0 10 98 97 114 123
joined = 103 0 0 0 10 98 97 114 123 0 0 10 98
</pre>
 
=={{header|PicoLisp}}==
Byte strings are represented in PicoLisp as lists of numbers. They can be
Line 1,843 ⟶ 3,217:
I/O of raw bytes is done via the 'wr' (write) and 'rd' (read) functions. The
following creates a file consisting of 256 bytes, with values from 0 to 255:
<langsyntaxhighlight PicoLisplang="picolisp">: (out "rawfile"
(mapc wr (range 0 255)) )</langsyntaxhighlight>
Looking at a hex dump of that file:
<langsyntaxhighlight PicoLisplang="picolisp">: (hd "rawfile")
00000000 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ................
00000010 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F ................
00000020 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F !"#$%&'()*+,-./
00000030 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 0123456789:;<=>?
...</langsyntaxhighlight>
To read part of that file, an external tool like 'dd' might be used:
<langsyntaxhighlight PicoLisplang="picolisp">: (in '(dd "skip=32" "bs=1" "count=16" "if=rawfile")
(make
(while (rd 1)
(link @) ) ) )
-> (32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47)</langsyntaxhighlight>
Now such byte lists can be assigned the normal way ('let', 'setq' etc.), they
can be compared with '=', '>', '>=' etc, and manipulated with all internal map-,
Line 1,864 ⟶ 3,238:
If desired, a string containing meaningful values can also be converted to
a transient symbol, e.g. the example above
<langsyntaxhighlight PicoLisplang="picolisp">: (pack (mapcar char (32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47)))
-> " !\"#$%&'()*+,-./"</langsyntaxhighlight>
 
=={{header|PL/I}}==
<syntaxhighlight lang="pl/i">
<lang PL/I>
/* PL/I has immediate facilities for all those operations except for */
/* replace. */
Line 1,891 ⟶ 3,264:
end;
end replace;
</syntaxhighlight>
</lang>
=={{header|PowerShell}}==
<syntaxhighlight lang="powershell">
Clear-Host
 
## String creation (which is string assignment):
Write-Host "`nString creation (which is string assignment):" -ForegroundColor Cyan
Write-Host '[string]$s = "Hello cruel world"' -ForegroundColor Yellow
[string]$s = "Hello cruel world"
 
## String (or any variable) destruction:
Write-Host "`nString (or any variable) destruction:" -ForegroundColor Cyan
Write-Host 'Remove-Variable -Name s -Force' -ForegroundColor Yellow
Remove-Variable -Name s -Force
 
## Now reassign the variable:
Write-Host "`nNow reassign the variable:" -ForegroundColor Cyan
Write-Host '[string]$s = "Hello cruel world"' -ForegroundColor Yellow
[string]$s = "Hello cruel world"
 
Write-Host "`nString comparison -- default is case insensitive:" -ForegroundColor Cyan
Write-Host '$s -eq "HELLO CRUEL WORLD"' -ForegroundColor Yellow
$s -eq "HELLO CRUEL WORLD"
Write-Host '$s -match "HELLO CRUEL WORLD"' -ForegroundColor Yellow
$s -match "HELLO CRUEL WORLD"
Write-Host '$s -cmatch "HELLO CRUEL WORLD"' -ForegroundColor Yellow
$s -cmatch "HELLO CRUEL WORLD"
 
## Copy a string:
Write-Host "`nCopy a string:" -ForegroundColor Cyan
Write-Host '$t = $s' -ForegroundColor Yellow
$t = $s
 
## Check if a string is empty:
Write-Host "`nCheck if a string is empty:" -ForegroundColor Cyan
Write-Host 'if ($s -eq "") {"String is empty."} else {"String = $s"}' -ForegroundColor Yellow
if ($s -eq "") {"String is empty."} else {"String = $s"}
 
## Append a byte to a string:
Write-Host "`nAppend a byte to a string:" -ForegroundColor Cyan
Write-Host "`$s += [char]46`n`$s" -ForegroundColor Yellow
$s += [char]46
$s
 
## Extract (and display) substring from a string:
Write-Host "`nExtract (and display) substring from a string:" -ForegroundColor Cyan
Write-Host '"Is the world $($s.Substring($s.IndexOf("c"),5))?"' -ForegroundColor Yellow
"Is the world $($s.Substring($s.IndexOf("c"),5))?"
 
## Replace every occurrence of a byte (or a string) in a string with another string:
Write-Host "`nReplace every occurrence of a byte (or a string) in a string with another string:" -ForegroundColor Cyan
Write-Host "`$t = `$s -replace `"cruel`", `"beautiful`"`n`$t" -ForegroundColor Yellow
$t = $s -replace "cruel", "beautiful"
$t
 
## Join strings:
Write-Host "`nJoin strings [1]:" -ForegroundColor Cyan
Write-Host '"Is the world $($s.Split()[1]) or $($t.Split()[1])?"' -ForegroundColor Yellow
"Is the world $($s.Split()[1]) or $($t.Split()[1])?"
Write-Host "`nJoin strings [2]:" -ForegroundColor Cyan
Write-Host '"{0} or {1}... I don''t care." -f (Get-Culture).TextInfo.ToTitleCase($s.Split()[1]), $t.Split()[1]' -ForegroundColor Yellow
"{0} or {1}... I don't care." -f (Get-Culture).TextInfo.ToTitleCase($s.Split()[1]), $t.Split()[1]
Write-Host "`nJoin strings [3] (display an integer array using the -join operater):" -ForegroundColor Cyan
Write-Host '1..12 -join ", "' -ForegroundColor Yellow
1..12 -join ", "
 
## Display an integer array in a tablular format:
Write-Host "`nMore string madness... display an integer array in a tablular format:" -ForegroundColor Cyan
Write-Host '1..12 | Format-Wide {$_.ToString().PadLeft(2)}-Column 3 -Force' -NoNewline -ForegroundColor Yellow
1..12 | Format-Wide {$_.ToString().PadLeft(2)} -Column 3 -Force
</syntaxhighlight>
{{Out}}
<pre>
String creation (which is string assignment):
[string]$s = "Hello cruel world"
 
String (or any variable) destruction:
Remove-Variable -Name s -Force
 
Now reassign the variable:
[string]$s = "Hello cruel world"
 
String comparison -- default is case insensitive:
$s -eq "HELLO CRUEL WORLD"
True
$s -match "HELLO CRUEL WORLD"
True
$s -cmatch "HELLO CRUEL WORLD"
False
 
Copy a string:
$t = $s
 
Check if a string is empty:
if ($s -eq "") {"String is empty."} else {"String = $s"}
String = Hello cruel world
 
Append a byte to a string:
$s += [char]46
$s
Hello cruel world.
 
Extract (and display) substring from a string:
"Is the world $($s.Substring($s.IndexOf("c"),5))?"
Is the world cruel?
 
Replace every occurrence of a byte (or a string) in a string with another string:
$t = $s -replace "cruel", "beautiful"
$t
Hello beautiful world.
 
Join strings [1]:
"Is the world $($s.Split()[1]) or $($t.Split()[1])?"
Is the world cruel or beautiful?
 
Join strings [2]:
"{0} or {1}... I don't care." -f (Get-Culture).TextInfo.ToTitleCase($s.Split()[1]), $t.Split()[1]
Cruel or beautiful... I don't care.
 
Join strings [3] (display an integer array using the -join operater):
1..12 -join ", "
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12
 
More string madness... display an integer array in a tablular format:
1..12 | Format-Wide {$_.ToString().PadLeft(2)}-Column 3 -Force
 
1 2 3
4 5 6
7 8 9
10 11 12
</pre>
=={{header|Prolog}}==
 
<syntaxhighlight lang="prolog">% Create a string (no destruction necessary)
?- X = "a test string".
X = "a test string".
 
% String assignment, there is no assignment but you can unify between variables, also 'String cloning and copying'
?- X = "a test string", X = Y.
X = Y, Y = "a test string".
 
% String comparison
?- X = "a test string", Y = "a test string", X = Y.
X = Y, Y = "a test string".
 
?- X = "a test string", Y = "a different string", X = Y.
false.
 
% Test for empty string, this is the same as string comparison.
?- X = "a test string", Y = "", X = Y.
false.
 
?- X = "", Y = "", X = Y.
false.
 
% Append a byte to a string
?- X = "a test string", string_concat(X, "!", Y).
X = "a test string",
Y = "a test string!".
 
% Extract a substring from a string
?- X = "a test string", sub_string(X, 2, 4, _, Y).
X = "a test string",
Y = "test".
 
?- X = "a test string", sub_string(X, Before, Len, After, test).
X = "a test string",
Before = 2,
Len = 4,
After = 7 ;
false.
 
% Replace every occurrence of a byte (or a string) in a string with another string
?- X = "a test string", re_replace('t'/g, 'o', X, Y).
X = "a test string",
Y = "a oeso soring".
 
% Join strings
?- X = "a test string", Y = " with extra!", string_concat(X, Y, Z).
X = "a test string",
Y = " with extra!",
Z = "a test string with extra!".
</syntaxhighlight>
=={{header|PureBasic}}==
<syntaxhighlight lang="purebasic">
<lang PureBasic>
;string creation
x$ = "hello world"
Line 1,921 ⟶ 3,475:
; join strings
x$ = "hel" + "lo w" + "orld"
</syntaxhighlight>
</lang>
 
=={{header|Python}}==
===2.x===
Line 1,929 ⟶ 3,482:
* String creation
 
<langsyntaxhighlight lang="python">s1 = "A 'string' literal \n"
s2 = 'You may use any of \' or " as delimiter'
s3 = """This text
goes over several lines
up to the closing triple quote"""</langsyntaxhighlight>
 
* String assignment
Line 1,939 ⟶ 3,492:
There is nothing special about assignments:
 
<langsyntaxhighlight lang="python">s = "Hello "
t = "world!"
u = s + t # + concatenates</langsyntaxhighlight>
 
* String comparison
Line 1,947 ⟶ 3,500:
They're compared byte by byte, lexicographically:
 
<langsyntaxhighlight lang="python">assert "Hello" == 'Hello'
assert '\t' == '\x09'
assert "one" < "two"
assert "two" >= "three"</langsyntaxhighlight>
 
* String cloning and copying
Line 1,958 ⟶ 3,511:
* Check if a string is empty
 
<langsyntaxhighlight lang="python">if x=='': print "Empty string"
if not x: print "Empty string, provided you know x is a string"</langsyntaxhighlight>
 
* Append a byte to a string
 
<langsyntaxhighlight lang="python">txt = "Some text"
txt += '\x07'
# txt refers now to a new string having "Some text\x07"</langsyntaxhighlight>
 
* Extract a substring from a string
Line 1,971 ⟶ 3,524:
Strings are sequences, they can be indexed with s[index] (index is 0-based) and sliced s[start:stop] (all characters from s[start] up to, but ''not'' including, s[stop])
 
<langsyntaxhighlight lang="python">txt = "Some more text"
assert txt[4] == " "
assert txt[0:4] == "Some"
assert txt[:4] == "Some" # you can omit the starting index if 0
assert txt[5:9] == "more"
assert txt[5:] == "more text" # omitting the second index means "to the end"</langsyntaxhighlight>
 
Negative indexes count from the end: -1 is the last byte, and so on:
 
<langsyntaxhighlight lang="python">txt = "Some more text"
assert txt[-1] == "t"
assert txt[-4:] == "text"</langsyntaxhighlight>
 
* Replace every occurrence of a byte (or a string) in a string with another string
Line 1,988 ⟶ 3,541:
Strings are objects and have methods, like replace:
 
<langsyntaxhighlight lang="python">v1 = "hello world"
v2 = v1.replace("l", "L")
print v2 # prints heLLo worLd</langsyntaxhighlight>
 
* Join strings
Line 1,996 ⟶ 3,549:
If they're separate variables, use the + operator:
 
<langsyntaxhighlight lang="python">v1 = "hello"
v2 = "world"
msg = v1 + " " + v2</langsyntaxhighlight>
 
If the elements to join are contained inside any iterable container (e.g. a list)
 
<langsyntaxhighlight lang="python">items = ["Smith", "John", "417 Evergreen Av", "Chimichurri", "481-3172"]
joined = ",".join(items)
print joined
# output:
# Smith,John,417 Evergreen Av,Chimichurri,481-3172</langsyntaxhighlight>
 
The reverse operation (split) is also possible:
 
<langsyntaxhighlight lang="python">line = "Smith,John,417 Evergreen Av,Chimichurri,481-3172"
fields = line.split(',')
print fields
# output:
# ['Smith', 'John', '417 Evergreen Av', 'Chimichurri', '481-3172']</langsyntaxhighlight>
 
===3.x===
Line 2,020 ⟶ 3,573:
 
To specify a literal immutable byte string (<code>bytes</code>), prefix a string literal with "b":
<langsyntaxhighlight lang="python">s1 = b"A 'byte string' literal \n"
s2 = b'You may use any of \' or " as delimiter'
s3 = b"""This text
goes over several lines
up to the closing triple quote"""</langsyntaxhighlight>
 
You can use the normal string escape sequences to encode special bytes.
 
Indexing a byte string results in an integer (the byte value at that byte):
<langsyntaxhighlight lang="python">x = b'abc'
x[0] # evaluates to 97</langsyntaxhighlight>
 
Similarly, a byte string can be converted to and from a list of integers:
 
<langsyntaxhighlight lang="python">x = b'abc'
list(x) # evaluates to [97, 98, 99]
bytes([97, 98, 99]) # evaluates to b'abc'</langsyntaxhighlight>
 
=={{header|Racket}}==
 
<langsyntaxhighlight lang="racket">
#lang racket
 
Line 2,088 ⟶ 3,640:
 
(bytes-join (list b2 b3) #" ") ; -> #"BBBBB BAAAA"
</syntaxhighlight>
</lang>
=={{header|Raku}}==
(formerly Perl 6)
{{Works with|rakudo|2018.03}}
<syntaxhighlight lang="raku" line># Raku is perfectly fine with NUL *characters* in strings:
my Str $s = 'nema' ~ 0.chr ~ 'problema!';
say $s;
 
# However, Raku makes a clear distinction between strings
=={{header|REXX}}==
# (i.e. sequences of characters), like your name, or …
Some older REXXes don't have a '''changestr''' bif, so one is included here.
my Str $str = "My God, it's full of chars!";
<lang REXX>/*REXX program shows ways to use and express binary strings. */
# … and sequences of bytes (called Bufs), for example a PNG image, or …
my Buf $buf = Buf.new(255, 0, 1, 2, 3);
say $buf;
 
# Strs can be encoded into Blobs …
dingsta='11110101'b /*4 versions, bit str assignment.*/
my Blob $this = 'round-trip'.encode('ascii');
dingsta="11110101"b /*same as above. */
# … and Blobs can be decoded into Strs …
dingsta='11110101'B /*same as above. */
my Str $that = $this.decode('ascii');
dingsta='1111 0101'B /*same as above. */
 
# So it's all there. Nevertheless, let's solve this task explicitly
dingst2=dingsta /*clone 1 str to another (copy). */
# in order to see some nice language features:
 
# We define a class …
other='1001 0101 1111 0111'b /*another binary (bit) string. */
class ByteStr {
# … that keeps an array of bytes, and we delegate some
# straight-forward stuff directly to this attribute:
# (Note: "has byte @.bytes" would be nicer, but that is
# not yet implemented in Rakudo.)
has Int @.bytes handles(< Bool elems gist push >);
 
# A handful of methods …
if dingsta=other then say 'they are equal' /*compare two strings.*/
method clone() {
self.new(:@.bytes);
}
 
method substr(Int $pos, Int $length) {
if other=='' then say 'OTHER is empty.' /*see if it's empty. */
self.new(:bytes(@.bytes[$pos .. $pos + $length - 1]));
if length(other)==0 then say 'OTHER is empty.' /*another version. */
}
 
method replace(*@substitutions) {
otherA=other || '$' /*append a dollar sign to OTHER. */
my %h = @substitutions;
otherB=other'$' /*same as above, with less fuss. */
@.bytes.=map: { %h{$_} // $_ }
}
}
 
# A couple of operators for our new type:
guts=substr(c2b(other),10,3) /*get the 10th through 12th bits.*/
multi infix:<cmp>(ByteStr $x, ByteStr $y) { $x.bytes.join cmp $y.bytes.join }
/*see sub below. Some REXXes */
multi infix:<~> (ByteStr $x, ByteStr $y) { ByteStr.new(:bytes(|$x.bytes, |$y.bytes)) }
/*have C2B as a built-in function*/
 
# create some byte strings (destruction not needed due to garbage collection)
new=changestr('A',other,"Z") /*change the letter A to Z. */
my ByteStr $b0 = ByteStr.new;
my ByteStr $b1 = ByteStr.new(:bytes( |'foo'.ords, 0, 10, |'bar'.ords ));
 
# assignment ($b1 and $b2 contain the same ByteStr object afterwards):
tt=changestr('~~',other,";") /*change 2 tildes to a semicolon.*/
my ByteStr $b2 = $b1;
 
# comparing:
joined=dignsta || dingst2 /*join 2 strs together (concat). */
say 'b0 cmp b1 = ', $b0 cmp $b1;
exit /*stick a fork in it, we're done.*/
say 'b1 cmp b2 = ', $b1 cmp $b2;
/*─────────────────────────────────C2B subroutine───────────────────────*/
 
c2b: return x2b(c2x(arg(1))) /*return the string as a binary string. */</lang>
# cloning:
Some older REXXes don't have a '''changestr''' bif, so one is included here ──► [[CHANGESTR.REX]].
my $clone = $b1.clone;
$b1.replace('o'.ord => 0);
say 'b1 = ', $b1;
say 'b2 = ', $b2;
say 'clone = ', $clone;
 
# to check for (non-)emptiness we evaluate the ByteStr in boolean context:
say 'b0 is ', $b0 ?? 'not empty' !! 'empty';
say 'b1 is ', $b1 ?? 'not empty' !! 'empty';
 
# appending a byte:
$b1.push: 123;
say 'appended = ', $b1;
 
# extracting a substring:
my $sub = $b1.substr(2, 4);
say 'substr = ', $sub;
 
# replacing a byte:
$b2.replace(102 => 103);
say 'replaced = ', $b2;
 
# joining:
my ByteStr $b3 = $b1 ~ $sub;
say 'joined = ', $b3;</syntaxhighlight>
 
{{out}}
Note: The ␀ represents a NUL byte.
<pre>nema␀problema!
Buf:0x<ff 00 01 02 03>
round-trip
b0 cmp b1 = Less
b1 cmp b2 = Same
b1 = [102 0 0 0 10 98 97 114]
b2 = [102 0 0 0 10 98 97 114]
clone = [102 111 111 0 10 98 97 114]
b0 is empty
b1 is not empty
appended = [102 0 0 0 10 98 97 114 123]
substr = [0 0 10 98]
replaced = [103 0 0 0 10 98 97 114 123]
joined = [103 0 0 0 10 98 97 114 123 0 0 10 98]</pre>
=={{header|Red}}==
<syntaxhighlight lang="rebol">Red []
s: copy "abc" ;; string creation
 
s: none ;; destruction
t: "Abc"
if t == "abc" [print "equal case"] ;; comparison , case sensitive
if t = "abc" [print "equal (case insensitive)"] ;; comparison , case insensitive
s: copy "" ;; copying string
if empty? s [print "string is empty "] ;; check if string is empty
append s #"a" ;; append byte
substr: copy/part at "1234" 3 2 ;; ~ substr ("1234" ,3,2) , red has 1 based indices !
?? substr
s: replace/all "abcabcabc" "bc" "x" ;; replace all "bc" by "x"
?? s
s: append "hello " "world" ;; join 2 strings
?? s
s: rejoin ["hello " "world" " !"] ;; join multiple strings
?? s
</syntaxhighlight>
{{out}}
<pre>equal (case insensitive)
string is empty
substr: "34"
s: "axaxax"
s: "hello world"
s: "hello world !"
>>
</pre>
=={{header|REXX}}==
Programming note: &nbsp; this REXX example demonstrates two types of &nbsp; ''quoting''.
<syntaxhighlight lang="rexx">/*REXX program demonstrates methods (code examples) to use and express binary strings.*/
dingsta= '11110101'b /*four versions, bit string assignment.*/
dingsta= "11110101"b /*this is the same assignment as above.*/
dingsta= '11110101'B /* " " " " " " " */
dingsta= '1111 0101'B /* " " " " " " */
 
dingsta2= dingsta /*clone one string to another (a copy).*/
other= '1001 0101 1111 0111'b /*another binary (or bit) string. */
if dingsta= other then say 'they are equal' /*compare the two (binary) strings. */
if other== '' then say "OTHER is empty." /*see if the OTHER string is empty.*/
otherA= other || '$' /*append a dollar sign ($) to OTHER. */
otherB= other'$' /*same as above, but with less fuss. */
guts= substr(c2b(other), 10, 3) /*obtain the 10th through 12th bits.*/
new= changeStr('A' , other, "Z") /*change the upper letter A ──► Z. */
tt= changeStr('~~', other, ";") /*change two tildes ──► one semicolon.*/
joined= dingsta || dingsta2 /*join two strings together (concat). */
say joined c2b(joined)
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
c2b: Return x2b(c2x(arg(1))) /*return the string as a binary string.*/</syntaxhighlight>
Some older REXXes don't have a &nbsp; '''changestr''' &nbsp; BIF, &nbsp; so one is included here &nbsp; ──► &nbsp; [[CHANGESTR.REX]].
<br><br>
{{out}}
<pre>§§ 1111010111110101</pre>
 
=={{header|Ring}}==
The String in the Ring programming language holds and manipulates an arbitrary sequence of bytes.
 
<syntaxhighlight lang="ring"># string creation
x = "hello world"
# string destruction
x = NULL
# string assignment with a null byte
x = "a"+char(0)+"b"
see len(x) # ==> 3
# string comparison
if x = "hello"
See "equal"
else
See "not equal"
ok
y = 'bc'
if strcmp(x,y) < 0
See x + " is lexicographically less than " + y
ok
# string cloning
xx = x
See x = xx # true, same length and content
 
# check if empty
if x = NULL
See "is empty"
ok
# append a byte
x += char(7)
# substring
x = "hello"
x[1] = "H"
See x + nl
# join strings
a = "hel"
b = "lo w"
c = "orld"
See a + b + c
</syntaxhighlight>
=={{header|RPL}}==
Strings are a sequence of bytes.
 
String creation:
"This is a new string" <span style="color:grey">@ String is put at stack level 1</span>
No need for destruction as there is a garbage collection mechanism.
 
String assignment:
"This is a string" '<span style="color:green">MYTEXT</span>' STO <span style="color:grey">@ String is transferred from stack level 1 to MYTEXT variable</span>
String comparison: numeric operators can be used for equality or lexicographic order
"This" "That" == <span style="color:grey">@ test equality - returns 0 here</span>
"This" "That" > <span style="color:grey">@ test order - returns 1 here</span>
Inclusion can also be tested:
"This" "is" POS <span style="color:grey">@ returns position of substring - 3 here</span>
String cloning and copying: any object, including strings, can be duplicated in the stack:
"This" DUP <span style="color:grey">@ Put a copy of "This" at stack level #2</span>
Check if a string is empty:
<span style="color:green">MYTEXT</span> "" == <span style="color:grey">@ returns 1 if MYTEXT contains an empty string</span>
or
<span style="color:green">MYTEXT</span> SIZE NOT <span style="color:grey">@ returns 1 if MYTEXT contains an empty string</span>
Append a byte to a string:
"Thi" "s" +
Extract a substring from a string:
"This is a string" 2 4 SUB <span style="color:grey">@ returns substring from 2nd to 4th character</span>
Replace every occurrence of a byte (or a string) in a string with another string: we need a small program here, since the REPL function replaces only the first occurence of the searched substring
≪ → string old new <span style="color:grey">@ store arguments</span>
≪ string <span style="color:grey">@ put string to be replaced in stack</span>
'''WHILE''' DUP old POS '''REPEAT''' <span style="color:grey">@ while old is present in string</span>
LAST SWAP new REPL <span style="color:grey">@ replace old by new</span>
'''END'''
≫ ≫ '<span style="color:blue">REPLALL</span>' STO
Join strings:
"This is" " a string" +
 
=={{header|Ruby}}==
A String object holds and manipulates an arbitrary sequence of bytes. There are also the [http://www.ruby-doc.org/core/classes/Array.html#M002222 Array#pack] and [http://www.ruby-doc.org/core/classes/String.html#M000760 String#unpack] methods to convert data to binary strings.
<langsyntaxhighlight lang="ruby"># string creation
x = "hello world"
Line 2,174 ⟶ 3,929:
b = "lo w"
c = "orld"
p d = a + b + c</langsyntaxhighlight>
 
=={{header|Run BASIC}}==
<langsyntaxhighlight lang="runbasic">' Create string
s$ = "Hello, world"
Line 2,209 ⟶ 3,964:
'join strings
s$ = "See " + "you " + "later."
print s$</langsyntaxhighlight>
=={{header|Rust}}==
For extra documentation, refer to [https://doc.rust-lang.org/std/string/struct.String.html] and [https://doc.rust-lang.org/book/strings.html].
<syntaxhighlight lang="rust">use std::str;
 
fn main() {
// Create new string
let string = String::from("Hello world!");
println!("{}", string);
assert_eq!(string, "Hello world!", "Incorrect string text");
 
// Create and assign value to string
let mut assigned_str = String::new();
assert_eq!(assigned_str, "", "Incorrect string creation");
assigned_str += "Text has been assigned!";
println!("{}", assigned_str);
assert_eq!(assigned_str, "Text has been assigned!","Incorrect string text");
 
// String comparison, compared lexicographically byte-wise same as the asserts above
if string == "Hello world!" && assigned_str == "Text has been assigned!" {
println!("Strings are equal");
}
 
// Cloning -> string can still be used after cloning
let clone_str = string.clone();
println!("String is:{} and Clone string is: {}", string, clone_str);
assert_eq!(clone_str, string, "Incorrect string creation");
 
// Copying, string won't be usable anymore, accessing it will cause compiler failure
let copy_str = string;
println!("String copied now: {}", copy_str);
 
// Check if string is empty
let empty_str = String::new();
assert!(empty_str.is_empty(), "Error, string should be empty");
 
// Append byte, Rust strings are a stream of UTF-8 bytes
let byte_vec = [65]; // contains A
let byte_str = str::from_utf8(&byte_vec).unwrap();
assert_eq!(byte_str, "A", "Incorrect byte append");
 
// Substrings can be accessed through slices
let test_str = "Blah String";
let mut sub_str = &test_str[0..11];
assert_eq!(sub_str, "Blah String", "Error in slicing");
sub_str = &test_str[1..5];
assert_eq!(sub_str, "lah ", "Error in slicing");
sub_str = &test_str[3..];
assert_eq!(sub_str, "h String", "Error in slicing");
sub_str = &test_str[..2];
assert_eq!(sub_str, "Bl", "Error in slicing");
 
// String replace, note string is immutable
let org_str = "Hello";
assert_eq!(org_str.replace("l", "a"), "Heaao", "Error in replacement");
assert_eq!(org_str.replace("ll", "r"), "Hero", "Error in replacement");
 
// Joining strings requires a `String` and an &str or a two `String`s one of which needs an & for coercion
let str1 = "Hi";
let str2 = " There";
let fin_str = str1.to_string() + str2;
assert_eq!(fin_str, "Hi There", "Error in concatenation");
 
// Joining strings requires a `String` and an &str or two `Strings`s, one of which needs an & for coercion
let str1 = "Hi";
let str2 = " There";
let fin_str = str1.to_string() + str2;
assert_eq!(fin_str, "Hi There", "Error in concatenation");
 
// Splits -- note Rust supports passing patterns to splits
let f_str = "Pooja and Sundar are up in Tumkur";
let split_str: Vec<_> = f_str.split(' ').collect();
assert_eq!(split_str, ["Pooja", "and", "Sundar", "are", "up", "in", "Tumkur"], "Error in string split");
}</syntaxhighlight>
=={{header|Seed7}}==
Seed7 strings are capable to hold binary data.
Line 2,272 ⟶ 4,099:
The [http://seed7.sourceforge.net/libraries/string.htm string.s7i] library contains
more string functions.
 
=={{header|Smalltalk}}==
Smalltalk strings are variable length and unrestricted. They are builtin and no additional library is req'd.
 
<langsyntaxhighlight Smalltalklang="smalltalk">s := "abc" # create a string (immutable if its a literal constant in the program)
s := #[16r01 16r02 16r00 16r03] asString # strings can contain any value, even nulls
s := String new:3. # a mutable string
Line 2,296 ⟶ 4,122:
s2 := s1 , $x # append a character
s2 := s1 , 123 asCharacter # append an arbitrary byte
s := 'Hello / 今日は' # they support unicode (at least up to 16rFFFF, some more)</langsyntaxhighlight>
 
In addition (because they inherit from collection), a lot more is inherited (map, fold, enumeration, finding substrings, etc.)
 
=={{header|Tcl}}==
Tcl strings are binary safe, and a binary string is any string that only contains UNICODE characters in the range <tt>\u0000</tt>–<tt>\u00FF</tt>.
<langsyntaxhighlight lang="tcl"># string creation
set x "hello world"
 
Line 2,337 ⟶ 4,162:
set b "lo w"
set c "orld"
set d $a$b$c</langsyntaxhighlight>
=={{header|VBA}}==
Before start, see this link :
https://msdn.microsoft.com/fr-fr/VBA/Language-Reference-VBA/articles/option-compare-statement :
<pre>The Option Compare instruction is used at module level to declare the default comparison method to use when string data is compared.
The default text comparison method is Binary.
</pre>
<syntaxhighlight lang="vb">
'Set the string comparison method to Binary.
Option Compare Binary ' That is, "AAA" is less than "aaa".
' Set the string comparison method to Text.
Option Compare Text ' That is, "AAA" is equal to "aaa".</syntaxhighlight>
String creation and destruction :
<syntaxhighlight lang="vb">
Sub Creation_String_FirstWay()
Dim myString As String
'Here, myString is created and equal ""
End Sub '==> Here the string is destructed !</syntaxhighlight>
String assignment :
<syntaxhighlight lang="vb">Sub String_Assignment()
Dim myString$
'Here, myString is created and equal ""
'assignments :
myString = vbNullString 'return : ""
myString = "Hello World" 'return : "Hello World"
myString = String(12, "A") 'return : "AAAAAAAAAAAA"
End Sub</syntaxhighlight>
String comparison :
<syntaxhighlight lang="vb">Sub String_Comparison_FirstWay()
Dim A$, B$, C$
 
If A = B Then Debug.Print "A = B"
A = "creation": B = "destruction": C = "CREATION"
'test equality : (operator =)
If A = B Then
Debug.Print A & " = " & B
'used to Sort : (operator < and >)
ElseIf A > B Then
Debug.Print A & " > " & B
Else 'here : A < B
Debug.Print A & " < " & B
End If
'test if A is different from C
If A <> C Then Debug.Print A & " and " & B & " are differents."
'same test without case-sensitive
If UCase(A) = UCase(C) Then Debug.Print A & " = " & C & " (no case-sensitive)"
'operator Like :
If A Like "*ation" Then Debug.Print A & " Like *ation"
If Not B Like "*ation" Then Debug.Print B & " Not Like *ation"
'See Also :
'https://docs.microsoft.com/en-us/dotnet/visual-basic/language-reference/operators/like-operator
End Sub</syntaxhighlight>
String cloning and copying :
<syntaxhighlight lang="vb">Sub String_Clone_Copy()
Dim A As String, B$
A = "Hello world!"
'cloning :
B = A
End Sub</syntaxhighlight>
Check if a string is empty :
<syntaxhighlight lang="vb">Sub Check_Is_Empty()
Dim A As String, B As Variant
 
Debug.Print IsEmpty(A) 'return False
Debug.Print IsEmpty(Null) 'return False
Debug.Print IsEmpty(B) 'return True ==> B is a Variant
 
Debug.Print A = vbNullString 'return True
Debug.Print StrPtr(A) 'return 0 (zero)
'Press the OK button without enter a data in the InputBox :
A = InputBox("Enter your own String : ")
Debug.Print A = "" 'return True
Debug.Print IsEmpty(A) 'return False
Debug.Print StrPtr(A) = 0 'return False
'Press the cancel button (with or without enter a data in the InputBox)
A = InputBox("Enter your own String : ")
Debug.Print StrPtr(A) = 0 'return True
Debug.Print IsEmpty(A) 'return False
Debug.Print A = "" 'return True
'Note : StrPtr is the only way to know if you cancel the inputbox
End Sub</syntaxhighlight>
Append a byte to a string :
<syntaxhighlight lang="vb">Sub Append_to_string()
Dim A As String
A = "Hello worl"
Debug.Print A & Chr(100) 'return : Hello world
End Sub</syntaxhighlight>
Extract a substring from a string :
<syntaxhighlight lang="vb">Sub ExtractFromString()
Dim A$, B As String
A = "Hello world"
B = Mid(A, 3, 8)
Debug.Print B 'return : llo worl
End Sub</syntaxhighlight>
Replace every occurrence of a byte (or a string) in a string with another string :
<syntaxhighlight lang="vb">Sub ReplaceInString()
Dim A$, B As String, C$
A = "Hello world"
B = Chr(108) ' "l"
C = " "
Debug.Print Replace(A, B, C) 'return : He o wor d
End Sub</syntaxhighlight>
Join Strings :
<syntaxhighlight lang="vb">Sub Join_Strings()
Dim A$, B As String
 
A = "Hello"
B = "world"
Debug.Print A & " " & B 'return : Hello world
'If you're sure that A and B are Strings, you can use + instead of & :
Debug.Print A + " " + B 'return : Hello world
End Sub
</syntaxhighlight>
=={{header|Visual Basic .NET}}==
{{trans|C#}}
<syntaxhighlight lang="vbnet">Module Module1
 
Sub Main()
'string creation
Dim x = "hello world"
 
' mark string for garbage collection
x = Nothing
 
' string assignment with a null byte
x = "ab" + Chr(0)
Console.WriteLine(x)
Console.WriteLine(x.Length)
 
'string comparison
If x = "hello" Then
Console.WriteLine("equal")
Else
Console.WriteLine("not equal")
End If
 
If x.CompareTo("bc") = -1 Then
Console.WriteLine("x is lexicographically less than 'bc'")
End If
 
'string cloning
Dim c(3) As Char
x.CopyTo(0, c, 0, 3)
Dim objecty As New String(c)
Dim y As New String(c)
 
Console.WriteLine(x = y) 'same as string.equals
Console.WriteLine(x.Equals(y)) 'it overrides object.equals
 
Console.WriteLine(x = objecty) 'uses object.equals, return false
 
'check if empty
Dim empty = ""
Dim nullString As String = Nothing
Dim whitespace = " "
If IsNothing(nullString) AndAlso empty = String.Empty _
AndAlso String.IsNullOrEmpty(nullString) AndAlso String.IsNullOrEmpty(empty) _
AndAlso String.IsNullOrWhiteSpace(nullString) AndAlso String.IsNullOrWhiteSpace(empty) _
AndAlso String.IsNullOrWhiteSpace(whitespace) Then
Console.WriteLine("Strings are null, empty or whitespace")
End If
 
'append a byte
x = "helloworld"
x += Chr(83)
Console.WriteLine(x)
 
'substring
Dim slice = x.Substring(5, 5)
Console.WriteLine(slice)
 
'replace bytes
Dim greeting = x.Replace("worldS", "")
Console.WriteLine(greeting)
 
'join strings
Dim join = greeting + " " + slice
Console.WriteLine(join)
End Sub
 
End Module</syntaxhighlight>
=={{header|Wren}}==
In Wren, a string is simply an array of bytes. Although they are typically characters stored in UTF-8 format, they don't have to be interpreted in that way and, in recognition of this as well as for efficiency reasons, many of the built-in string functions operate at the byte level.
 
Despite this, there is no separate byte type - one just uses a single character string instead.
 
Strings are immutable and assignment creates a new copy rather than a reference to the original string.
 
All strings belong to the built-in String class which does not have an explicit constructor. To create one you either use a literal (a series of characters enclosed in double quotes) or assign an existing string.
 
When there are no longer any references to a string it is automatically garbage collected. You can't really destroy a string manually though you can request an immediate garbage collection be performed by calling the ''System.gc()'' method.
 
Setting a string variable to the special value ''null'' means that the variable currently has no value though it can still be assigned one later.
<syntaxhighlight lang="wren">// create string
var s = "abc"
 
// destroy string (not really see notes above)
s = null
 
// (re)assignment
s = "def"
 
// comparison (only == && != supported directly)
var b = (s == "abc") // false
 
// cloning/copying
var t = s
 
// check if empty
s = ""
b = (s != "") // false
b = s.isEmpty // true
 
// append a byte
s = s + "b"
 
// extract a substring
s = "ghijkl"
t = s[1..4] // "hijk"
 
// replace a byte or string
s = "abracadabra"
s = s.replace("a", "z") // "zbrzczdzbrz"
 
// join strings
s = "abc"
t = "def"
var u = s + t // "abcdef"</syntaxhighlight>
 
=={{header|Yabasic}}==
<syntaxhighlight lang="yabasic">// Rosetta Code problem: http://rosettacode.org/wiki/Binary_strings
// by Galileo, 07/2022
 
// Create string
s$ = "Hello, world"
// String destruction
s$ = ""
// String comparison
If s$ = "Hello, world" print "Equal String"
// Copying string
a$ = s$
// Check If empty
If s$ = "" print "String is MT"
// Append a byte
s$ = s$ + Chr$(65)
// Extract a substring
a$ = Mid$(s$, 1, 5) // bytes 1 -> 5
//substitute string "world" with "universe"
a$ = "Hello, world"
for i = 1 to len(a$)
if mid$(a$,i,5)="world" then
a$=left$(a$,i-1)+"universe"+mid$(a$,i+5)
end if
next
print a$
//join strings
s$ = "See " + "you " + "later."
print s$</syntaxhighlight>
{{out}}
<pre>String is MT
Hello, universe
See you later.
---Program done, press RETURN---</pre>
=={{header|zkl}}==
Strings in zkl are bytes with a zero terminator. So they are binary safe as long as the data doesn't contain a zero. Data objects are true binary strings: bytes with a length. It is basically a binary editor. Datas come in two flavors: Int and String. The difference is some methods treat String type as containing (zero or more) null terminated strings. Datas have an implicit null terminator so they can easily convert to a String.
<langsyntaxhighlight lang="zkl">Data(0,.Int,1,2,3) // bytes
Data(0,String,1,2,3) // same
Data(0,Int,"foo","bar") //-->foobar\0
Line 2,361 ⟶ 4,463:
 
d2:=Data(0,Int,"sam");
d.append(d2).text // or d+d2</langsyntaxhighlight>
 
{{omit from|AWK}}
{{omit from|GUISS}}
{{omit from|Lotus 123 Macro Scripting}}
416

edits