Copy a string
This task is about copying a string.

You are encouraged to solve this task according to the task description, using any language you may know.
- Task
Where it is relevant, distinguish between copying the contents of a string versus making an additional reference to an existing string.
- Metrics
- Counting
- Word frequency
- Letter frequency
- Jewels and stones
- I before E except after C
- Bioinformatics/base count
- Count occurrences of a substring
- Count how many vowels and consonants occur in a string
- Remove/replace
- XXXX redacted
- Conjugate a Latin verb
- Remove vowels from a string
- String interpolation (included)
- Strip block comments
- Strip comments from a string
- Strip a set of characters from a string
- Strip whitespace from a string -- top and tail
- Strip control codes and extended characters from a string
- Anagrams/Derangements/shuffling
- Word wheel
- ABC problem
- Sattolo cycle
- Knuth shuffle
- Ordered words
- Superpermutation minimisation
- Textonyms (using a phone text pad)
- Anagrams
- Anagrams/Deranged anagrams
- Permutations/Derangements
- Find/Search/Determine
- ABC words
- Odd words
- Word ladder
- Semordnilap
- Word search
- Wordiff (game)
- String matching
- Tea cup rim text
- Alternade words
- Changeable words
- State name puzzle
- String comparison
- Unique characters
- Unique characters in each string
- Extract file extension
- Levenshtein distance
- Palindrome detection
- Common list elements
- Longest common suffix
- Longest common prefix
- Compare a list of strings
- Longest common substring
- Find common directory path
- Words from neighbour ones
- Change e letters to i in words
- Non-continuous subsequences
- Longest common subsequence
- Longest palindromic substrings
- Longest increasing subsequence
- Words containing "the" substring
- Sum of the digits of n is substring of n
- Determine if a string is numeric
- Determine if a string is collapsible
- Determine if a string is squeezable
- Determine if a string has all unique characters
- Determine if a string has all the same characters
- Longest substrings without repeating characters
- Find words which contains all the vowels
- Find words which contain the most consonants
- Find words which contains more than 3 vowels
- Find words whose first and last three letters are equal
- Find words with alternating vowels and consonants
- Formatting
- Substring
- Rep-string
- Word wrap
- String case
- Align columns
- Literals/String
- Repeat a string
- Brace expansion
- Brace expansion using ranges
- Reverse a string
- Phrase reversals
- Comma quibbling
- Special characters
- String concatenation
- Substring/Top and tail
- Commatizing numbers
- Reverse words in a string
- Suffixation of decimal numbers
- Long literals, with continuations
- Numerical and alphabetical suffixes
- Abbreviations, easy
- Abbreviations, simple
- Abbreviations, automatic
- Song lyrics/poems/Mad Libs/phrases
- Mad Libs
- Magic 8-ball
- 99 bottles of beer
- The Name Game (a song)
- The Old lady swallowed a fly
- The Twelve Days of Christmas
- Tokenize
- Text between
- Tokenize a string
- Word break problem
- Tokenize a string with escaping
- Split a character string based on change of character
- Sequences
V src = ‘hello’ V dst = copy(src)To copy a string, we use an MVC (Move Character). To make a reference to a string, we use a LA (Load Address).
* Duplicate a string MVC A,=CL64'Hello' a='Hello' MVC B,A b=a memory copy MVC A,=CL64'Goodbye' a='Goodbye' XPRNT A,L'A print a XPRNT B,L'B print b ... * Make reference to a string a string MVC A,=CL64'Hi!' a='Hi!' LA R1,A r1=@a set pointer ST R1,REFA refa=@a store pointer XPRNT A,L'A print a XPRNT 0(R1),L'A print %refa ... A DS CL64 a B DS CL64 b REFA DS A @asource equ $10 ;$10 was chosen arbitrarily source_hi equ source+1 ;the high byte MUST be after the low byte, otherwise this will not work. dest equ $12 dest_hi equ dest+1 LDA #<MyString ;get the low byte of &MyString STA source LDA #>MyString ;get the high byte STA source_hi ;we just created a "shallow reference" to an existing string. ;As it turns out, this is a necessary step to do a deep copy. LDA #<RamBuffer STA dest LDA #>RamBuffer STA dest_hi strcpy: ;assumes that RamBuffer is big enough to hold the source string, and that the memory ranges do not overlap. ;if you've ever wondered why C's strcpy is considered "unsafe", this is why. LDY #0 .again: LDA (source),y STA (dest),y BEQ .done INY BNE .again ;exit after 256 bytes copied or the null terminator is reached, whichever occurs first. RTS MyString: byte "hello",0 RamBuffer: byte 0,0,0,0,0,0Making a reference to an existing string is simple. Just load its memory location into an address register.
myString: DC.B "HELLO WORLD",0 EVEN LEA myString,A3 Copying a string involves a little more work:
StringRam equ $100000 myString: DC.B "HELLO WORLD",0 EVEN LEA myString,A3 LEA StringRam,A4 CopyString: MOVE.B (A3)+,(A4)+ ;Copy one byte. BNE CopyString ;Not zero, do more bytes. ;program ends here. The technique varies depending on whether you just want a new reference to the old string or to actually duplicate it in RAM. Strangely, this is one of the few things that's actually easier to do correctly in assembly than in high-level languages - it's very unlikely you'll do the wrong one by accident.
Making a new reference
This technique is useful if you wish to create a struct/record that needs to be able to retrieve a string quickly. All you need to do is get a pointer to the desired string and store it in RAM.
.model small .stack 1024 .data myString byte "Hello World!",0 ; a null-terminated string myStruct word 0 .code mov ax,@data mov ds,ax ;load data segment into DS mov bx,offset myString ;get the pointer to myString mov word ptr [ds:myStruct],bx mov ax,4C00h int 21h ;quit program and return to DOS Creating a "deep copy"
This method will actually make a byte-for-byte copy somewhere else in RAM.
.model small .stack 1024 .data myString byte "Hello World!",0 ; a null-terminated string StringRam byte 256 dup (0) ;256 null bytes .code mov ax,@data mov ds,ax ;load data segment into DS mov es,ax ;also load it into ES mov si,offset myString mov di,offset StringRam mov cx,12 ;length of myString cld ;make MOVSB auto-increment rather than auto-decrement (I'm pretty sure DOS begins with ;the direction flag cleared but just to be safe) rep movsb ;copies 12 bytes from [ds:si] to [es:di] mov al,0 ;create a null terminator stosb ;store at the end. (It's already there since we initialized StringRam to zeroes, but you may need to do this depending ;on what was previously stored in StringRam, if you've copied a string there already. mov ax,4C00h int 21h ;quit program and return to DOS /* ARM assembly AARCH64 Raspberry PI 3B */ /* program copystr64.s */ /*******************************************/ /* Constantes file */ /*******************************************/ /* for this file see task include a file in language AArch64 assembly*/ .include "../includeConstantesARM64.inc" /*******************************************/ /* Initialized data */ /*******************************************/ .data szString: .asciz "ABCDEFGHIJKLMNOPQRSTUVWXYZ\n" /*******************************************/ /* UnInitialized data */ /*******************************************/ .bss .align 4 qPtString: .skip 8 szString1: .skip 80 /*******************************************/ /* code section */ /*******************************************/ .text .global main main: // entry of program // display start string ldr x0,qAdrszString bl affichageMess // copy pointer string ldr x0,qAdrszString ldr x1,qAdriPtString str x0,[x1] // control ldr x1,qAdriPtString ldr x0,[x1] bl affichageMess // copy string ldr x0,qAdrszString ldr x1,qAdrszString1 1: ldrb w2,[x0],1 // read one byte and increment pointer one byte strb w2,[x1],1 // store one byte and increment pointer one byte cmp x2,#0 // end of string ? bne 1b // no -> loop // control ldr x0,qAdrszString1 bl affichageMess 100: // standard end of the program */ mov x0,0 // return code mov x8,EXIT // request to exit program svc 0 // perform the system call qAdrszString: .quad szString qAdriPtString: .quad qPtString qAdrszString1: .quad szString1 /********************************************************/ /* File Include fonctions */ /********************************************************/ /* for this file see task include a file in language AArch64 assembly */ .include "../includeARM64.inc"data: lv_string1 type string value 'Test', lv_string2 type string. lv_string2 = lv_string1. Inline Declaration
DATA(string1) = |Test|. DATA(string2) = string1. PROC Main() CHAR ARRAY str1,str2,str3(10) str1="Atari" str2=str1 SCopy(str3,str1) PrintF(" base=%S%E",str1) PrintF("alias=%S%E",str2) PrintF(" copy=%S%E",str3) PutE() SCopy(str1,"Action!") PrintF(" base=%S%E",str1) PrintF("alias=%S%E",str2) PrintF(" copy=%S%E",str3) RETURN- Output:
Screenshot from Atari 8-bit computer
base=Atari alias=Atari copy=Atari base=Action! alias=Action! copy=Atari
Strings are immutable in ActionScript, and can safely be assigned with the assignment operator, much as they can in Java.[1]
var str1:String = "Hello"; var str2:String = str1; Ada provides three different kinds of strings. The String type is a fixed length string. The Bounded_String type is a string with variable length up to a specified maximum size. The Unbounded_String type is a variable length string with no specified maximum size. The Bounded_String type behaves a lot like C strings, while the Unbounded_String type behaves a lot like the C++ String class.
Fixed Length String Copying.
Src : String := "Hello"; Dest : String := Src; Ada provides the ability to manipulate slices of strings.
Src : String := "Rosetta Stone"; Dest : String := Src(1..7); -- Assigns "Rosetta" to Dest Dest2 : String := Src(9..13); -- Assigns "Stone" to Dest2 Bounded Length String Copying
-- Instantiate the generic package Ada.Strings.Bounded.Generic_Bounded_Length with a maximum length of 80 characters package Flexible_String is new Ada.Strings.Bounded.Generic_Bounded_Length(80); use Flexible_String; Src : Bounded_String := To_Bounded_String("Hello"); Dest : Bounded_String := Src; Ada Bounded_String type provides a number of functions for dealing with slices.
Unbounded Length String Copying
-- The package Ada.Strings.Unbounded contains the definition of the Unbounded_String type and all its methods Src : Unbounded_String := To_Unbounded_String("Hello"); Dest : Unbounded_String := Src; The intrinsic text type is immediate, immutable and cannot be referred more than once.
Copying an intrinsic string:
text s, t; t = "Rosetta"; s = t;Data of the non intrinsic byte array type can be referred more than once. Copying a binary array of bytes:
data s, t; # Copy -t- into -s- b_copy(s, t); # Set -s- as a reference of the object -t- is pointing b_set(s, t); # or: s = t;In ALGOL 68 strings are simply flexible length arrays of CHAR;
( STRING src:="Hello", dest; dest:=src )begin % strings are (fixed length) values in algol W. Assignment makes a copy % string(10) a, copyOfA; a := "some text"; copyOfA := a; % assignment to a will not change copyOfA % a := "new value"; write( a, copyOfA ) end.- Output:
new value some text
In Apex, Strings are a primitive data type
String original = 'Test'; String cloned = original; //"original == cloned" is true cloned += ' more'; //"original == cloned" is falseset src to "Hello" set dst to src Variables are always copied in ArkScript, thus assigning a new variable with the content of another won't create a reference.
(mut str "hello world") (mut copy str) (set copy "clone destroyed") (print str) (print copy)- Output:
hello world clone destroyed
/* ARM assembly Raspberry PI */ /* program copystr.s */ /* Constantes */ .equ STDOUT, 1 @ Linux output console .equ EXIT, 1 @ Linux syscall .equ WRITE, 4 @ Linux syscall /* Initialized data */ .data szString: .asciz "ABCDEFGHIJKLMNOPQRSTUVWXYZ\n" /* UnInitialized data */ .bss .align 4 iPtString: .skip 4 szString1: .skip 80 /* code section */ .text .global main main: /* entry of program */ push {fp,lr} /* saves 2 registers */ @ display start string ldr r0,iAdrszString bl affichageMess @ copy pointer string ldr r0,iAdrszString ldr r1,iAdriPtString str r0,[r1] @ control ldr r1,iAdriPtString ldr r0,[r1] bl affichageMess @ copy string ldr r0,iAdrszString ldr r1,iAdrszString1 1: ldrb r2,[r0],#1 @ read one byte and increment pointer one byte strb r2,[r1],#1 @ store one byte and increment pointer one byte cmp r2,#0 @ end of string ? bne 1b @ no -> loop @ control ldr r0,iAdrszString1 bl affichageMess 100: /* standard end of the program */ mov r0, #0 @ return code pop {fp,lr} @restaur 2 registers mov r7, #EXIT @ request to exit program swi 0 @ perform the system call iAdrszString: .int szString iAdriPtString: .int iPtString iAdrszString1: .int szString1 /******************************************************************/ /* display text with size calculation */ /******************************************************************/ /* r0 contains the address of the message */ affichageMess: push {fp,lr} /* save registres */ push {r0,r1,r2,r7} /* save others registers */ mov r2,#0 /* counter length */ 1: /* loop length calculation */ ldrb r1,[r0,r2] /* read octet start position + index */ cmp r1,#0 /* if 0 its over */ addne r2,r2,#1 /* else add 1 in the length */ bne 1b /* and loop */ /* so here r2 contains the length of the message */ mov r1,r0 /* address message in r1 */ mov r0,#STDOUT /* code to write to the standard output Linux */ mov r7, #WRITE /* code call system "write" */ swi #0 /* call systeme */ pop {r0,r1,r2,r7} /* restaur others registers */ pop {fp,lr} /* restaur des 2 registres */ bx lr /* return */a: new "Hello" b: a ; reference the same string ; changing one string in-place ; will change both strings 'b ++ "World" print b print a c: "Hello" d: new c ; make a copy of the older string ; changing one string in-place ; will change only the string in question 'd ++ "World" print d print c - Output:
HelloWorld HelloWorld HelloWorld Hello
string src, dst; src = "Hello"; dst = src; src = " world..."; write(dst, src); src := "Hello" dst := src $Src= "Hello" $dest = $Src BEGIN { a = "a string" b = a sub(/a/, "X", a) # modify a print b # b is a copy, not a reference to... } Lbl STRCPY r₁→S While {r₂} {r₂}→{r₁} r₁++ r₂++ End 0→{r₁} S ReturnTo copy a string in Babel is the same as copying any other object. Use the cp operator to make a deep-copy.
babel> "Hello, world\n" dup cp dup 0 "Y" 0 1 move8 babel> << << Yello, world Hello, worldsrc$ = "Hello" dst$ = src$
100 DEF FN P(A) = PEEK (A) + PEEK(A + 1) * 256 : FOR I = FN P(105) TO FN P(107) - 1 STEP 7 : ON PEEK(I + 1) < 128 OR PEEK(I) > 127 GOTO 130 : ON LEFT$(P$, 1) <> CHR$(PEEK(I)) GOTO 130 110 IF LEN(P$) > 1 THEN ON PEEK(I + 1) = 128 GOTO 130 : IF MID$(P$, 2, 1) <> CHR$(PEEK(I + 1) - 128) GOTO 130 120 POKE I + 4, P / 256 : POKE I + 3, P - PEEK(I + 4) * 256 : RETURN 130 NEXT I : STOPS$ = "HELLO" : REM S$ IS THE ORIGINAL STRING C$ = S$ : REM C$ IS THE COPYP$ = "S" : P = 53637 : GOSUB 100"POINT STRING S AT SOMETHING ELSE ?S$ ?C$Strings by value or by reference
Strings can be stored by value or by reference. By value means that a copy of the original string is stored in a variable. This happens automatically when when a string variable name ends with the '$' symbol.
Sometimes it may be necessary to refer to a string by reference. In such a case, simply declare a variable name as STRING but omit the '$' at the end. Such a variable will point to the same memory location as the original string. The following examples should show the difference between by value and by reference.
When using string variables by value:
a$ = "I am here" b$ = a$ a$ = "Hello world..." PRINT a$, b$ This will print "Hello world...I am here". The variables point to their individual memory areas so they contain different strings. Now consider the following code:
a$ = "Hello world..." LOCAL b TYPE STRING b = a$ a$ = "Goodbye..." PRINT a$, b This will print "Goodbye...Goodbye..." because the variable 'b' points to the same memory area as 'a$'.
src$ = "Hello" dst$ = src$ src$ = " world..." print dst$; src$ 10 A$ = "HELLO" 20 REM COPY CONTENTS OF A$ TO B$ 30 B$ = A$ 40 REM CHANGE CONTENTS OF A$ 50 A$ = "WORLD" 60 REM DISPLAY CONTENTS 70 PRINT A$, B$ src$ = "Hello" ' is the original string dst$ = src$ ' is the copy src$ = " world..." PRINT dst$; src$ src = "Hello" dst = src src = " world..." PRINT dst; src
LET src$ = "Hello" LET dst$ = src$ LET src$ = " world..." PRINT dst$; src$ END src$ = "Hello" dst$ = src$ src$ = " world..." print dst$, src$ end10 A$ = "HELLO" 20 REM COPY CONTENTS OF A$ TO B$ 30 B$ = A$ 40 REM CHANGE CONTENTS OF A$ 50 A$ = "HI" 60 REM DISPLAY CONTENTS 70 PRINT A$, B$ Commodore BASIC can't do pointers or 'reference to'
Creating a new reference to an existing string is not possible, or at least not easy. (You could probably do it with PEEKs and POKEs.) This program demonstrates that an assignment statement copies a string, by showing that the two strings can afterwards be independently modified.
10 LET A$="BECAUSE I DO NOT HOPE TO TURN AGAIN" 20 LET B$=A$ 30 LET A$=A$( TO 21) 40 PRINT B$ 50 PRINT A$ 60 LET B$=A$+B$(22 TO 29) 70 PRINT B$ - Output:
BECAUSE I DO NOT HOPE TO TURN AGAIN BECAUSE I DO NOT HOPE BECAUSE I DO NOT HOPE TO TURN
Since the only variables are environment variables, creating a string copy is fairly straightforward:
set src=Hello set dst=%src% source$ = "Hello, world!" REM Copy the contents of a string: copy$ = source$ PRINT copy$ REM Make an additional reference to a string: !^same$ = !^source$ ?(^same$+4) = ?(^source$+4) ?(^same$+5) = ?(^source$+5) PRINT same$ ^ Hello_world! v _v >0>::2g\1p1+:2g48*`^ v!`*84g1:+1,g1:<0$< @_ ^
- Output:
Hello_world!
In BLC, every value is immutable, including byte-strings. So one never needs to copy them; references are shared.
BQN strings are character arrays. Like all other types of arrays, they are immutable.
String copying in BQN is left to be defined by the implementation, but CBQN and mlochbaum/BQN(main implementations) copy only the reference until the original source is modified.
a ← "Hello" b ← a •Show a‿b a ↩ "hi" •Show a‿b ⟨ "Hello" "Hello" ⟩ ⟨ "hi" "Hello" ⟩ Because in Bracmat strings are unalterable, you never want to copy a string. Still, you will obtain a copy of a string by overflowing the reference counter of the string. (Currently, reference counters on strings and on most operators are 10 bits wide. The = operator has a much wider 'inexhaustible' reference counter, because it anchors alterable objects.) Still, you won't be able to test whether you got the original or a copy other than by looking at overall memory usage of the Bracmat program at the OS-level or by closely timing comparison operations. You obtain a new reference to a string or a copy of the string by simple assignment using the = or the : operator:
abcdef:?a; !a:?b; c=abcdef; !c:?d; !a:!b { variables a and b are the same and probably referencing the same string } !a:!d { variables a and d are also the same but not referencing the same string }#include <stdlib.h>/* exit(), free() */ #include <stdio.h>/* fputs(), perror(), printf() */ #include <string.h> int main() { size_t len; char src[] = "Hello"; char dst1[80], dst2[80]; char *dst3, *ref; /* * Option 1. Use strcpy() from <string.h>. * * DANGER! strcpy() can overflow the destination buffer. * strcpy() is only safe if the source string is shorter than * the destination buffer. We know that "Hello" (6 characters * with the final '\0') easily fits in dst1 (80 characters). */ strcpy(dst1, src); /* * Option 2. Use strlen() and memcpy() from <string.h>, to copy * strlen(src) + 1 bytes including the final '\0'. */ len = strlen(src); if (len >= sizeof dst2) { fputs("The buffer is too small!\n", stderr); exit(1); } memcpy(dst2, src, len + 1); /* * Option 3. Use strdup() from <string.h>, to allocate a copy. */ dst3 = strdup(src); if (dst3 == NULL) { /* Failed to allocate memory! */ perror("strdup"); exit(1); } /* Create another reference to the source string. */ ref = src; /* Modify the source string, not its copies. */ memset(src, '-', 5); printf(" src: %s\n", src); /* src: ----- */ printf("dst1: %s\n", dst1); /* dst1: Hello */ printf("dst2: %s\n", dst2); /* dst2: Hello */ printf("dst3: %s\n", dst3); /* dst3: Hello */ printf(" ref: %s\n", ref); /* ref: ----- */ /* Free memory from strdup(). */ free(dst3); return 0; } #include <stdlib.h>/* exit() */ #include <stdio.h>/* fputs(), printf() */ #include <string.h> int main() { char src[] = "Hello"; char dst[80]; /* Use strlcpy() from <string.h>. */ if (strlcpy(dst, src, sizeof dst) >= sizeof dst) { fputs("The buffer is too small!\n", stderr); exit(1); } memset(src, '-', 5); printf("src: %s\n", src); /* src: ----- */ printf("dst: %s\n", dst); /* dst: Hello */ return 0; } Versión 2, using Gadget library.
Link:
https://github.com/DanielStuardo/Gadget
#include <gadget/gadget.h> LIB_GADGET_START Main String v, w = "this message is a message"; Let( v, "Hello world!"); Print "v = %s\nw = %s\n\n", v,w; Get_fn_let( v, Upper(w) ); Print "v = %s\nw = %s\n\n", v,w; Stack{ Store ( v, Str_tran_last( Upper(w), "MESSAGE", "PROOF" ) ); }Stack_off; Print "v = %s\nw = %s\n\n", v,w; Free secure v, w; End - Output:
v = Hello world! w = this message is a message v = THIS MESSAGE IS A MESSAGE w = this message is a message v = THIS MESSAGE IS A PROOF w = this message is a message
string src = "Hello"; string dst = src; #include <iostream> #include <string> int main( ) { std::string original ("This is the original"); std::string my_copy = original; std::cout << "This is the copy: " << my_copy << std::endl; original = "Now we change the original! "; std::cout << "my_copy still is " << my_copy << std::endl; } (let [s "hello" s1 s] (println s s1)) MOVE "Hello" TO src MOVE src TO dst In ColdFusion, only complex data types (structs, objects, etc.) are passed by reference. Hence, any string copy operations are by value.
<cfset stringOrig = "I am a string." /> <cfset stringCopy = stringOrig />(let* ((s1 "Hello") ; s1 is a variable containing a string (s1-ref s1) ; another variable with the same value (s2 (copy-seq s1))) ; s2 has a distinct string object with the same contents (assert (eq s1 s1-ref)) ; same object (assert (not (eq s1 s2))) ; different object (assert (equal s1 s2)) ; same contents (fill s2 #\!) ; overwrite s2 (princ s1) (princ s2)) ; will print "Hello!!!!!" VAR str1: ARRAY 128 OF CHAR; str2: ARRAY 32 OF CHAR; str3: ARRAY 25 OF CHAR; ...
str1 := "abcdefghijklmnopqrstuvwxyz"; str3 := str1; (* don't compile, incompatible assignement *) str3 := str1$; (* runtime error, string too long *) str2 := str1$; (* OK *) Assuming a string to be a zero-terminated array of bytes, this program takes a string beginning at address src and makes a copy of it beginning at address dest. As an example, we copy the string "Rosetta".
ldsrc: LDA src stdest: STA dest BRZ done ; 0-terminated LDA ldsrc ADD one STA ldsrc LDA stdest ADD one STA stdest JMP ldsrc done: STP one: 1 src: 82 ; ASCII 111 115 101 116 116 97 0 dest:s1 = "Hello" s2 = s1 void main() { string src = "This is a string"; // copy contents: auto dest1 = src.idup; // copy contents to mutable char array auto dest2 = src.dup; // copy just the fat reference of the string auto dest3 = src; } main() { var s1 = 'hello'; var s2 = s1; print(s2); } [a string] # push "a string" on the main stack d # duplicate the top value f # show the current contents of the main stack- Output:
a string a string
Delphi strings are reference counted with copy on write semantics.
program CopyString; {$APPTYPE CONSOLE} var s1: string; s2: string; begin s1 := 'Goodbye'; s2 := s1; // S2 points at the same string as S1 s2 := s2 + ', World!'; // A new string is created for S2 Writeln(s1); Writeln(s2); end. - Output:
Goodbye Goodbye, World!
Behind the scenes, the DuckDB engine is free to optimize storage e.g. by compressing strings, but logically, strings are immutable, as illustrated in the following transcript. The "D " in the transcript is the DuckDB prompt.
D create or replace table t as (select 'This is a string' as s); D from t; ┌──────────────────┐ │ s │ │ varchar │ ├──────────────────┤ │ This is a string │ └──────────────────┘ # Now make two copies. D create or replace table tt as (select s as s1, s as s2 from t); D from tt; ┌──────────────────┬──────────────────┐ │ s1 │ s2 │ │ varchar │ varchar │ ├──────────────────┼──────────────────┤ │ This is a string │ This is a string │ └──────────────────┴──────────────────┘ # Change s2 and then verify that s1 is unaltered D UPDATE tt SET s2 = s2[1]; D from tt; ┌──────────────────┬─────────┐ │ s1 │ s2 │ │ varchar │ varchar │ ├──────────────────┼─────────┤ │ This is a string │ T │ └──────────────────┴─────────┘ # Check that s and s1 are also still equal D select s = s1 from t positional join tt; ┌──────────┐ │ (s = s1) │ │ boolean │ ├──────────┤ │ true │ └──────────┘ DWScript strings are value-type, from the language point of view, you can't have a reference to a String, no more than you can have a reference to an Integer or a Float (unless you wrap in an object of course).
Internally they're transparently implemented via either immutable reference or copy-on-write.
Strings in Dyalect are immutable:
var src = "foobar" var dst = srcIn Déjà Vu, strings are immutable, so there really isn't a good reason to copy them. As such, no standard way of doing so is provided. However, one can still create a copy of a string by concatenating it with an empty string.
local :orgininal "this is the original" local :scopy concat( original "" ) !. scopy- Output:
"this is the original"
E is a pass-references-by-value object-oriented language, and strings are immutable, so there is never a need for or benefit from copying a string. Various operations, such as taking the substring (run) from the beginning to the end (someString.run(0)) might create a copy, but this is not guaranteed.
a$ = "hello" b$ = a$ print b$ Strings are immutable. A copy will return the same object.
(define-syntax-rule (string-copy s) (string-append s)) ;; copy = append nothing → #syntax:string-copy (define s "abc") (define t (string-copy s)) t → "abc" (eq? s t) → #t ;; same reference, same object Copies the current buffer contents in its entirety.
,tExpects the final character of a string to be marked with a 1 in the least significant bit, as in Hello world/Line printer#EDSAC order code. The source string should be loaded at θ+34; it is copied into storage tank 6. The copy is then printed out.
[ Copy a string ============= A program for the EDSAC Copies the source string into storage tank 6, which is assumed to be free, and then prints it from there Works with Initial Orders 2 ] T56K GK [ 0 ] A34@ [ copy the string ] [ 1 ] T192F [ 2 ] H34@ C32@ S32@ E17@ T31@ A@ A33@ T@ A1@ A33@ T1@ A2@ A33@ T2@ E@ [ 17 ] O192F [ print the copy ] [ 18 ] H192F C32@ S32@ E30@ T31@ A17@ A33@ T17@ A18@ A33@ T18@ E17@ [ 30 ] ZF [ 31 ] PF [ 32 ] PD [ 33 ] P1F [ 34 ] *F RF OF SF EF TF TF AF !F CF OF DF ED EZPF- Output:
ROSETTA CODE
var src := "Hello"; var dst := src; // copying the reference var copy := src.clone(); // copying the contentsrc = "Hello" dst = src (let* ((str1 "hi") (str1-ref str1) (str2 (copy-sequence str1))) (eq str1 str1-ref) ;=> t (eq str1 str2) ;=> nil (equal str1 str1-ref) ;=> t (equal str1 str2)) ;=> t ^|in EMal strings are mutable|^ text original ← "Yellow world" text ref ← original # copying the reference text copied ← *original # copying the content original[0] ← "H" # texts are indexable and mutable original[5] ← "," ref.append("!") # texts are coercible and growable copied += "?" writeLine(original æ ref and original æ "Hello, world!") writeLine(copied æ "Yellow world?")- Output:
⊤ ⊤
Src = "Hello". Dst = Src. Arrays in many languages are constrained to have a fixed number of elements, and those elements must all be of the same type. Euphoria eliminates both of those restrictions by defining all arrays (sequences) as a list of zero or more Euphoria objects whose element count can be changed at any time. When you retrieve a sequence element, it is not guaranteed to be of any type. You, as a programmer, need to check that the retrieved data is of the type you'd expect, Euphoria will not. The only thing it will check is whether an assignment is legal. For example, if you try to assign a sequence to an integer variable, Euphoria will complain at the time your code does the assignment.
sequence first = "ABC" sequence newOne = first.NET strings are immutable, so it is usually not useful to make a deep copy. However if needed, it is possible using a static method of the System.String type:
let str = "hello" let additionalReference = str let deepCopy = System.String.Copy( str ) printfn "%b" <| System.Object.ReferenceEquals( str, additionalReference ) // prints true printfn "%b" <| System.Object.ReferenceEquals( str, deepCopy ) // prints false Factor strings are mutable but not growable. Strings will be immutable in a future release.
"This is a mutable string." dup ! reference "Let's make a deal!" dup clone ! copy "New" " string" append . ! new string "New string" Factor string buffers (sbufs) are mutable and growable.
SBUF" Grow me!" dup " OK." append SBUF" Grow me! OK." Convert a string buffer to a string.
SBUF" I'll be a string someday." >string . "I'll be a string someday." Forth strings are generally stored in memory as prefix counted string, where the first byte contains the string length. However, on the stack they are most often represented as <addr cnt> pairs. Thus the way you copy a string depends on where the source string comes from:
\ Allocate two string buffers create stringa 256 allot create stringb 256 allot \ Copy a constant string into a string buffer s" Hello" stringa place \ Copy the contents of one string buffer into another stringa count stringb place str2 = str1 Because Fortran uses fixed length character strings if str1 is shorter than str2 then str2 is padded out with trailing spaces. If str1 is longer than str2 it is truncated to fit.
' FB 1.05.0 Win64 Dim s As String = "This is a string" Dim t As String = s ' a separate copy of the string contents has been made as can be seen from the addresses Print s, StrPtr(s) Print t, StrPtr(t) ' to refer to the same string a pointer needs to be used Dim u As String Ptr = @s Print Print *u, StrPtr(*u) Sleep - Output:
This is a string 10623504 This is a string 10623552 This is a string 10623504
Strings are immutable after construction, so "copying" a string just creates a new reference to a string. All string manipulation routines return a new string.
a = "Monkey" b = ainclude "NSLog.incl" CFStringRef original, copy original = @"Hello!" copy = fn StringWithString( original ) NSLog( @"%@", copy ) HandleEvents Output:
Hello!
Note that the DIM statement is required in Gambas.
Click this link to run this code
Public Sub main() Dim src As String Dim dst As String src = "Hello" dst = src Print src Print dst End #In GAP strings are lists of characters. An affectation simply copy references a := "more"; b := a; b{[1..4]} := "less"; a; # "less" # Here is a true copy a := "more"; b := ShallowCopy(a); b{[1..4]} := "less"; a; # "more" src = "string"; dest = src;Just use assignment:
src := "Hello" dst := src Strings in Go are immutable. Because of this, there is no need to distinguish between copying the contents and making an additional reference. Technically, Go strings are immutable byte slices. A slice is an object that contains a reference to an underlying array. In the assignment shown above, a new slice object is created for dst. Its internal reference is likely to point to the same underlying array as src, but the language does not specify this behavior or make any guarantees about it.
package main import "fmt" func main() { // creature string var creature string = "shark" // point to creature var pointer *string = &creature // creature string fmt.Println("creature =", creature) // creature = shark // creature location in memory fmt.Println("pointer =", pointer) // pointer = 0xc000010210 // creature through the pointer fmt.Println("*pointer =", *pointer) // *pointer = shark // set creature through the pointer *pointer = "jellyfish" // creature through the pointer fmt.Println("*pointer =", *pointer) // *pointer = jellyfish // creature string fmt.Println("creature =", creature) // creature = jellyfish }
;"abc".
. creates a new string. If you modify the contents of this string, the original string is not changed:
1+ ]p
- Output:
["abc" "abc1"]
The dynamics of references and object creation are very much the same as in Java. However, the meaning of the equality (==) operator is different in Groovy, so we show those differences here, even though they are not relevant to the actual copying.
Example and counter-example:
def string = 'Scooby-doo-bee-doo' // assigns string object to a variable reference def stringRef = string // assigns another variable reference to the same object def stringCopy = new String(string) // copies string value into a new object, and assigns to a third variable reference Test Program:
assert string == stringRef // they have equal values (like Java equals(), not like Java ==) assert string.is(stringRef) // they are references to the same objext (like Java ==) assert string == stringCopy // they have equal values assert ! string.is(stringCopy) // they are references to different objects (like Java !=) Caveat Lector: Strings are immutable objects in Groovy, so it is wasteful and utterly unnecessary to ever make copies of them within a Groovy program.
Start.Programs,Accessories,Notepad, Type:Hello world[pling],Highlight:Hello world[pling], Menu,Edit,Copy,Menu,Edit,PastecSource := "Hello World" cDestination := cSource In Haskell, every value is immutable, including Strings. So one never needs to copy them; references are shared.
src = "Hello World" dst = src//Strings are immutable in 'i'. software { a = "Hello World" b = a //This copies the string. a += "s" print(a) print(b) }Strings in Icon are immutable.
Under the covers 'b' is created as a reference to the same string as 'a'; the sub-string assignment creates a new copy of the string. However, there is no way to tell this in the language. While most of the time this is transparent, programs that create very long strings through repeated concatenation need to avoid generating intermediate strings. Instead using a list and concatenating at the last minute can perform much better.
Note that strings are indicated using double quotes. However, single quotes are another type called character sets or csets.
src =: 'hello' dest =: src J has copy-on-write semantics. So both src and dest are references to the same memory, until src changes, at which time dest retains a copy of the original value of src.
In Java, Strings are immutable, so it doesn't make that much difference to copy it.
String src = "Hello"; String newAlias = src; String strCopy = new String(src); //"newAlias == src" is true //"strCopy == src" is false //"strCopy.equals(src)" is true Instead, maybe you want to create a StringBuffer (mutable string) from an existing String or StringBuffer:
StringBuffer srcCopy = new StringBuffer("Hello"); Objects can be copied in JavaScript via simple reassignment. Changes to the properties of one will be reflected in the other:
var container = {myString: "Hello"}; var containerCopy = container; // Now both identifiers refer to the same object containerCopy.myString = "Goodbye"; // container.myString will also return "Goodbye" If you copy property values with reassignment, such as properties of the global object (window in browsers), only the value will be copied and not the reference
var a = "Hello"; var b = a; // Same as saying window.b = window.a b = "Goodbye" // b contains a copy of a's value and a will still return "Hello" "hello" dupStrings are immutable.
jq is a functional language and all data types, including strings, are immutable. If a string were to be copied (e.g. by exploding and imploding it), the resultant string would be equal in all respects to the original, and from the jq programmer's perspective, the two would be identical.
jq does however have a type of variable, though their values actually don't change -- they are just context-dependent. For example, consider the sequence of steps in the following function:
def demo: "abc" as $s # assignment of a string to a variable | $s as $t # $t points to the same string as $s | "def" as $s # This $s shadows the previous $s | $t # $t still points to "abc" ; demo- Output:
"abc"
Strings are immutable in Julia. Assignment of one string valued variable to another is effectively a copy, as subsequent changes to either variable have no effect on the other.
s = "Rosetta Code" t = s println("s = \"", s, "\" and, after \"t = s\", t = \"", t, "\"") s = "Julia at "*s println("s = \"", s, "\" and, after this change, t = \"", t, "\"") - Output:
s = "Rosetta Code" and, after "t = s", t = "Rosetta Code" s = "Julia at Rosetta Code" and, after this change, t = "Rosetta Code"
Var:String str1 = "Hello"; Var:String str2 = str1;val s = "Hello" val alias = s // alias === s val copy = "" + s // copy !== s In LabVIEW, one can simply wire an input to more than one output.
This image is a VI Snippet, an executable image of LabVIEW code. The LabVIEW version is shown on the top-right hand corner. You can download it, then drag-and-drop it onto the LabVIEW block diagram from a file browser, and it will appear as runnable, editable code.
{def S1 hello world} // set S1 to "hello world" -> S1 {S1} // get the value of S1 -> hello world {def S2 S1} // define S2 as S1 -> S2 {S2} // the value of S2 is S1 -> S1 {{S2}} // get the value of the value of S2 -> hello world {def S3 {S1}} // set S3 to the value of S1 -> S3 {S3} // get the value of S3 -> hello world 'hello dupWhile other datatypes like arrays require ->asCopy & ->asCopyDeep methods, assigning strings creates a copy, not a reference, as is seen below.
local(x = 'I saw a rhino!') local(y = #x) #x //I saw a rhino! '\r' #y //I saw a rhino! '\r\r' #x = 'I saw one too' #x //I saw one too '\r' #y //I saw a rhino! '\r\r' #y = 'it was grey.' #x //I saw one too '\r' #y //it was grey. Strings are immutable in Latitude, so it is seldom necessary to explicitly copy one. However, a copy can be distinguished from the original using ===
a := "Hello". b := a. c := a clone. println: a == b. ; True println: a == c. ; True println: a === b. ; True println: a === c. ; FalseCopying a string is the same as copying any other zero-terminated array. This program copies the string at SRC to COPY, then prints the copy to show it has worked.
.ORIG 0x3000 LEA R1,SRC LEA R2,COPY LOOP LDR R3,R1,0 STR R3,R2,0 BRZ DONE ADD R1,R1,1 ADD R2,R2,1 BRNZP LOOP DONE LEA R0,COPY PUTS HALT SRC .STRINGZ "What, has this thing appeared again tonight?" COPY .BLKW 128 .END- Output:
What, has this thing appeared again tonight?
(let* ((a '"data assigned to a") (b a)) (: io format '"Contents of 'b': ~s~n" (list b))) - Output:
Contents of 'b': data assigned to a
One can also use set to copy a sting when one is in the LFE REPL:
> (set a '"data") "data" > a "data" > (set b a) "data" > b "data" src$ = "Hello" dest$ = src$ print src$ print dest$str = "Hello world!" str2 = strSyntax-wise strings are not immuatable in Lingo. You can alter an existing string without new assignment:
put "X" before str put "X" after str put "X" into char 6 of str put str -- "XHellX world!X"But memory-wise they are immutable: Lingo internally stores references to strings, and as soon as a string is altered, a new copy is created on the fly, so other references to the original string are not affected by the change.
+ scon : STRING_CONSTANT; + svar : STRING; scon := "sample"; svar := STRING.create 20; svar.copy scon; svar.append "!\n"; svar.print;STRING_CONSTANT is immutable, STRING is not.
string a = "A string"; string b = a; a =~ s/$/\./; puts(a); puts(b); put "foo" into bar put bar into baz answer bar && bazCopies are nearly always made, on function calls parameters may be passed by reference (pointer) by prepending @ to a parameter in the function definition, however this is the only case where it is usually performed.
As a functional language, words are normally treated as symbols and cannot be modified. The EQUAL? predicate compares contents instead of identity. In UCB Logo the .EQ predicate tests for "thing" identity.
make "a "foo make "b "foo print .eq :a :b ; true, identical symbols are reused make "c :a print .eq :a :c ; true, copy a reference make "c word :b "|| ; force a copy of the contents of a word by appending the empty word print equal? :b :c ; true print .eq :b :c ; falseLua strings are immutable, so only one reference to each string exists.
a = "string" b = a print(a == b) -->true print(b) -->string In Maple, you cannot really copy a string in the sense that there can be two copies of the string in memory. As soon as you create a second copy of a string that already exists, it get turned into a reference to the first copy. However, you can copy a reference to a string by a simple assignment statement.
> s := "some string"; s := "some string" > t := "some string"; t := "some string" > evalb( s = t ); # they are equal true > addressof( s ) = addressof( t ); # not just equal data, but the same address in memory 3078334210 = 3078334210 > u := t: # copy reference a="Hello World" b=a string1 = 'Hello'; string2 = string1; /* It's possible in Maxima to access individual characters by subscripts, but it's not the usual way. Also, the result is "Lisp character", which cannot be used by other Maxima functions except cunlisp. The usual way to access characters is charat, returning a "Maxima character" (actually a one characte string). With the latter, it's impossible to modify a string in place, thus scopy is of little use. */ a: "loners"$ b: scopy(a)$ c: a$ c[2]: c[5]$ a; "losers" b; "loners" c; "losers" str1 = "Hello" str2 = copy str1Metafont will always copy a string (does not make references).
string s, a; s := "hello"; a := s; s := s & " world"; message s; % writes "hello world" message a; % writes "hello" endphrase = "hi" copy = phrase print phrase print copy This does a full copy of the string, not just copying the pointer to the string's contents.
.data .text strcpy: addi $sp, $sp, -4 sw $s0, 0($sp) add $s0, $zero, $zero L1: add $t1, $s0, $a1 lb $t2, 0($t1) add $t3, $s0, $a0 sb $t2, 0($t3) beq $t2, $zero, L2 addi $s0, $s0, 1 j L1 L2: lw $s0, 0($sp) addi $sp, $sp, 4 jr $ra src = "Hello" new_alias = src puts 'interned strings are equal' if src == new_alias str_copy = String.new(src) puts 'non-interned strings are not equal' if str_copy != src puts 'compare strings with equals()' if str_copy.equals(src)Strings in Modula-3 have the type TEXT.
VAR src: TEXT := "Foo"; VAR dst: TEXT := src; SET S1="Greetings, Planet" SET S2=S1 a = "Hello" b = avar src = "Hello" var dst = srcNemerle gives you the option of declaring a variable - even a string - as mutable, so the caveats of languages with only immutable strings don't necessarily apply. However, Nemerle binds the value of the string to the new name when copying; to sort of emulate copying a reference you can use lazy evaluation.
using System; using System.Console; using Nemerle; module StrCopy { Main() : void { mutable str1 = "I am not changed"; // str1 is bound to literal def str2 = lazy(str1); // str2 will be bound when evaluated def str3 = str1; // str3 is bound to value of str1 str1 = "I am changed"; // str1 is bound to new literal Write($"$(str1)\n$(str2)\n$(str3)\n"); // str2 is bound to value of str1 // Output: I am changed // I am changed // I am not changed } } In addition to the string capabilities provided by the Java String libraries (see Java for some examples) NetRexx provides comprehensive string capabilities through the built-in Rexx type. Rexx strings can be copied by simple assignment; as follows:
/* NetRexx */ options replace format comments java crossref symbols nobinary s1 = 'This is a Rexx string' s2 = s1 s2 = s2.changestr(' ', '_') say s1 say s2 In this example a string is created, the string is copied then the copy is modified with the changestr built-in function. Finally both strings are displayed to confirm that the original string wasn't modified by the call to changestr.
- Output:
This is a Rexx string This_is_a_Rexx_string
(define (assert f msg) (if (not f) (println msg))) (setq s "Greetings!" c (copy s)) (reverse c) ; Modifies c in place. (assert (= s c) "Strings not equal.") ; another way ; Nehal-Singhal 2018-05-25 > (setq a "abcd") "abcd" > (setq b a) "abcd" > b "abcd" > (= a b) true var c = "This is a string" d = c # Copy c into a new string 10 A$ = "HELLO" 20 B$ = A$ 30 A$ = "HI" 40 PRINT A$, B$MODULE CopyString; TYPE String = ARRAY 128 OF CHAR; VAR a,b: String; BEGIN a := "plain string"; COPY(a,b); END CopyString. a := "GoodBye!"; b := a;Immutable strings - since they are immutable, you may get the same instance with its references count increased. Or, you can get a copy which is mutable if you use mutableCopy. Remember that both copy and mutableCopy return a retained instance. You can also get a copy by doing [NSString stringWithString:] or [[NSString alloc] initWithString:].
Note that both copy and initWithString:/stringWithString: are optimized to return the original string object (possibly retained) if it is immutable.
NSString *original = @"Literal String"; NSString *new = [original copy]; NSString *anotherNew = [NSString stringWithString:original]; NSString *newMutable = [original mutableCopy]; Mutable strings - you can get either new mutable (if you use mutableCopy) or immutable (if you use copy) string:
NSMutableString *original = [NSMutableString stringWithString:@"Literal String"]; NSString *immutable = [original copy]; NSString *anotherImmutable = [NSString stringWithString:original]; NSMutableString *mutable = [original mutableCopy]; Copying a CString into an NSString:
const char *cstring = "I'm a plain C string"; NSString *string = [NSString stringWithUTF8String:cstring]; Copying from data, possibly not null terminated:
char bytes[] = "some data"; NSString *string = [[NSString alloc] initWithBytes:bytes length:9 encoding:NSASCIIStringEncoding]; And of course, if a C string is needed, you can use standard functions like strcpy.
let src = "foobar"
Before OCaml 4.02 (2014), strings were mutable and explicit deep copying was needed:
let dst = String.copy src
Between 4.02 and 4.06 (2017), immutable strings were optionally enabled via a flag: -safe-string. A Bytes module was added to provide safe and unsafe mutable views on strings. The two modules were synonymous unless the aforementioned flag was added.
(* Transition-period synonymy between types, explicit type annotations are just for emphasis *) let dst1 : string = Bytes.copy (src : bytes) let dst2 : bytes = Bytes.copy (src : string) (* fails to compile with -safe-string *)
After 4.06, immutable strings became the default, Bytes still exists, but its type is now distinct. The only way to get mutable strings and type synonymy back is at configure-time on the compiler itself.
String.copy issues a deprecation warning, and a (shallow) copy would simply be an assignment by default:
let dst = src To get a mutable deep-copy still, just convert the string to bytes via Bytes.of_string, which copies for safety, or String.sub/map/init/.. for an immutable copy.
depending on your compiler version, choose the example accordingly.
str2 = str1To make a copy of the reference, just dup the string
"abcde" dupThere is no need to copy a string content as strings are immutable. If really needed :
StringBuffer new "abcde" <<(define a "The String.") ; copy the string (define b (runes->string (string->runes a))) (print "a: " a) (print "b: " b) (print "b is an a: " (eq? a b)) (print "b same as a: " (equal? a b)) ; another way: marshal the string (define c (fasl-decode (fasl-encode a) #f)) (print "a: " a) (print "c: " c) (print "c is an a: " (eq? a c)) (print "c same as a: " (equal? a c))- Output:
a: The String. b: The String. b is an a: #false b same as a: #true a: The String. c: The String. c is an a: #false c same as a: #true
/* Rexx *************************************************************** * 16.05.2013 Walter Pachl **********************************************************************/ s1 = 'This is a Rexx string' s2 = s1 /* does not copy the string */ Say 's1='s1 Say 's2='s2 i1=s1~identityhash; Say 's1~identityhash='i1 i2=s2~identityhash; Say 's2~identityhash='i2 s2 = s2~changestr('*', '*') /* creates a modified copy */ Say 's1='s1 Say 's2='s2 i1=s1~identityhash; Say 's1~identityhash='i1 i2=s2~identityhash; Say 's2~identityhash='i2- Output:
s1=This is a Rexx string s2=This is a Rexx string s1~identityhash=17587366586244 s2~identityhash=17587366586244 s1=This is a Rexx string s2=This is a Rexx string s1~identityhash=17587366586244 s2~identityhash=17587366588032
Tested with Psion Series 3a & Series 5. source
PROC main: LOCAL src$(6),dst$(5) src$="Hello" dst$=src$ src$="world!" PRINT dst$,src$ GET ENDPstring s, t="hello" s=tAssignment in GP always copies.
s1=sIn PARI, strings can be copied and references can be made.
GEN string_copy = gcopy(string); GEN string_ref = string;See also: Delphi
program copyAString; var { The Extended Pascal `string` schema data type is essentially a `packed array[1..capacity] of char`. } source, destination: string(80); begin source := 'Hello world!'; { In Pascal _whole_ array data type values can be copied by assignment. } destination := source; { Provided `source` is a _non-empty_ string value you can copy in Extended Pascal sub-ranges _of_ _string_ types, too. Note, the sub-range notation is not permitted for a `bindable` data type. } destination := source[1..length(source)]; { You can also employ Extended Pascal’s `writeStr` routine: } writeStr(destination, source); end.Strings in PascalABC.NET are references.
begin var s: string := 'Hello'; var s1 := s; end.To copy a string, just use ordinary assignment:
my $original = 'Hello.'; my $new = $original; $new = 'Goodbye.'; print "$original\n"; # prints "Hello."To create a reference to an existing string, so that modifying the referent changes the original string, use a backslash:
my $original = 'Hello.'; my $ref = \$original; $$ref = 'Goodbye.'; print "$original\n"; # prints "Goodbye."If you want a new name for the same string, so that you can modify it without dereferencing a reference, assign a reference to a typeglob:
my $original = 'Hello.'; our $alias; local *alias = \$original; $alias = 'Good evening.'; print "$original\n"; # prints "Good evening."Note that our $alias, though in most cases a no-op, is necessary under stricture. Beware that local binds dynamically, so any subroutines called in this scope will see (and possibly modify!) the value of $alias assigned here.
To make a lexical variable that is an alias of some other variable, the Lexical::Alias module can be used:
use Lexical::Alias; my $original = 'Hello.'; my $alias; alias $alias, $original; $alias = 'Good evening.'; print "$original\n"; # prints "Good evening."Use of strings is utterly intuitive with no unexpected side effects. For example
string one = "feed" string two = one -- (two becomes "feed", one remains "feed") two[2..3] = "oo" -- (two becomes "food", one remains "feed") one[1] = 'n' -- (two remains "food", one becomes "need") ?{one,two}
- Output:
{"need","food"} Phix variables are reference counted (except for integers). When a simple copy is made, it increases the reference count and shares the data, making it very fast on large sequences and long strings. Attempts to modify any data with a reference count greater than one cause a copy to be made, and all other variables are left unchanged. Strings can be modified "in situ", no problem.
$src = "Hello"; $dst = $src;Use copy_term/1 to ensure that the original string is not changed.
go => S1 = "string", println(s1=S1), S2 = S1, S2[1] := 'x', % also changes S1 println(s1=S1), println(s2=S2), nl, S3 = "string", S4 = copy_term(S3), S4[1] := 'x', % no change of S3 println(s3=S3), println(s4=S4), nl.- Output:
s1 = string s1 = xtring s2 = xtring s3 = string s4 = xtring
(setq Str1 "abcdef") (setq Str2 Str1) # Create a reference to that symbol (setq Str3 (name Str1)) # Create new symbol with name "abcdef"int main(){ string hi = "Hello World."; string ih = hi; } declare (s1, s2) character (20) varying; s1 = 'now is the time'; s2 = s1;Like Lua, Pluto strings are immutable. Only one reference of each string exists in memory.
a = "Hello" b = a print(a==b)- Output:
true
In Pop11 normal data are represented by references, so plain assignment will copy references. To copy data one has to use copy procedure:
vars src, dst; 'Hello' -> src; copy(src) -> dst;One can also combine assignment (initialization) with variable declarations:
vars src='Hello'; vars dst=copy(src);In PostScript,
(hello) dup length string copySince PowerShell uses .NET behind the scenes and .NET strings are immutable you can simply assign the same string to another variable without breaking anything:
$str = "foo" $dup = $strTo actually create a copy the Clone() method can be used:
$dup = $str.Clone()editvar /newvar /value=a /userinput=1 /title=Enter a string to be copied: editvar /newvar /value=b /userinput=1 /title=Enter current directory of the string: editvar /newvar /value=c /userinput=1 /title=Enter file to copy to: copy -a- from -b- to -c-Values in Prolog are immutable so unifying with a variable that already has the value of a string will effectively copy that string. You cannot reassign a value once it has been unified, it is not logical to have a value equal more than one thing.
?- A = "A test string", A = B. A = B, B = "A test string".src$ = "Hello" dst$ = src$Since strings are immutable, all copy operations return the same string, with the reference count increased as appropriate
>>> src = "hello" >>> a = src >>> b = src[:] >>> import copy >>> c = copy.copy(src) >>> d = copy.deepcopy(src) >>> src is a is b is c is d TrueTo actually copy a string:
>>> a = 'hello' >>> b = ''.join(a) >>> a == b True >>> b is a ### Might be True ... depends on "interning" implementation details! FalseAs a result of object "interning" some strings such as the empty string and single character strings like 'a' may be references to the same object regardless of copying. This can potentially happen with any Python immutable object and should be of no consequence to any proper code.
Be careful with is - use it only when you want to compare the identity of the object. To compare string values, use the == operator. For numbers and strings any given Python interpreter's implementation of "interning" may cause the object identities to coincide. Thus any number of names to identical numbers or strings might become references to the same objects regardless of how those objects were derived (even if the contents were properly "copied" around). The fact that these are immutable objects makes this a reasonable behavior.
Strings are immutable.
$ "hello" dupCopy a string by value:
str1 <- "abc" str2 <- str1#lang racket (let* ([s1 "Hey"] [s2 s1] [s3 (string-copy s1)] [s4 s3]) (printf "s1 and s2 refer to ~a strings\n" (if (eq? s1 s2) "the same" "different")) ; same (printf "s1 and s3 refer to ~a strings\n" (if (eq? s1 s3) "the same" "different")) ; different (printf "s3 and s4 refer to ~a strings\n" (if (eq? s3 s4) "the same" "different")) ; same (string-fill! s3 #\!) (printf "~a~a~a~a\n" s1 s2 s3 s4)) ; outputs "HeyHey!!!!!!"(formerly Perl 6)
There is no special handling needed to copy a string; just assign it to a new variable:
my $original = 'Hello.'; my $copy = $original; say $copy; # prints "Hello." $copy = 'Goodbye.'; say $copy; # prints "Goodbye." say $original; # prints "Hello."You can also bind a new variable to an existing one so that each refers to, and can modify the same string.
my $original = 'Hello.'; my $bound := $original; say $bound; # prints "Hello." $bound = 'Goodbye.'; say $bound; # prints "Goodbye." say $original; # prints "Goodbye."
Copy a string by reference:
'abc' as a a as bCopy a string by value:
'abc' as a a copy as bRebol [ Title: "String Copy" URL: http://rosettacode.org/wiki/Copy_a_string ] x: y: "Testing." y/2: #"X" print ["Both variables reference same string:" mold x "," mold y] x: "Slackeriffic!" print ["Now reference different strings:" mold x "," mold y] y: copy x ; String copy here! y/3: #"X" ; Modify string. print ["x copied to y, then modified:" mold x "," mold y] y: copy/part x 7 ; Copy only the first part of y to x. print ["Partial copy:" mold x "," mold y] y: copy/part skip x 2 3 print ["Partial copy from offset:" mold x "," mold y]- Output:
Script: "String Copy" (16-Dec-2009) Both variables reference same string: "TXsting." , "TXsting." Now reference different strings: "Slackeriffic!" , "TXsting." x copied to y, then modified: "Slackeriffic!" , "SlXckeriffic!" Partial copy: "Slackeriffic!" , "Slacker" Partial copy from offset: "Slackeriffic!" , "ack"
Red[] originalString: "hello wordl" copiedString: originalString ; OR copiedString2: copy originalString'this_is_a_string dup s:tempInclude How to use
Include Source code
-- 8 Nov 2025 include Setting say 'COPY A STRING' say version say say 'Just assign the string variable to a new one.' a='This is a string.' b=a say a b c="This is also a string." d=c say d c exit include Abend- Output:
COPY A STRING REXX-Regina_3.9.7(MT) 5.00 18 Mar 2025 Just assign the string variable to a new one. This is a string. This is a string. This is also a string. This is also a string.
cStr1 = "Hello!" # create original string cStr2 = cStr1 # make new string from original>> s1 = "A string" A string >> s2 = s1 A stringset "$string1" to "This is a string" set "$string2" to "$string1" * "&$string2&"Copy a string in stack:
DUP
Copy a string from one variable to another:
"Example" 'STR1' STO STR1 'STR2' STO
In Ruby, String are mutable.
original = "hello" reference = original # copies reference copy1 = original.dup # instance of original.class copy2 = String.new(original) # instance of String original << " world!" # append p reference #=> "hello world!" p copy1 #=> "hello" p copy2 #=> "hello"There is a method of Object#clone, too, in the copy of the object.
original = "hello".freeze # prevents further modifications copy1 = original.dup # copies contents (without status) copy2 = original.clone # copies contents (with status) p copy1.frozen? #=> false p copy1 << " world!" #=> "hello world!" p copy2.frozen? #=> true p copy2 << " world!" #=> can't modify frozen String (RuntimeError)origString$ = "Hello!" ' create original string newString$ = origString$ ' make new strig from originalfn main() { let s1 = "A String"; let mut s2 = s1; s2 = "Another String"; println!("s1 = {}, s2 = {}", s1, s2); }Output:
s1 = A String, s2 = Another Stringclass MAIN is main is s ::= "a string"; s1 ::= s; -- s1 is a copy end; end;Creating a copy of a string requires only a simple assignment. The effect of a reference can be obtained by declaring a base-located string and positioning it at run-time on top of the original string, the address of which can be obtained using the LOCATION statement Since they occupy the same memory, any change to the original string will be reflected in the base-located string and vice-versa.
var original, copy = string based referenced = string var strloc = integer rem - position referenced string on top of original string location var strloc = original base referenced at strloc original = "Hello, World" copy = original print "Original : ", original print "Copy : ", copy print "Referenced: ", referenced print original = "Goodbye, World" print "Original : ", original rem - changed print "Copy : ", copy rem - unchanged print "Referenced: ", referenced rem - changed end- Output:
Original : Hello, World Copy : Hello, World Referenced: Hello, World Original : Goodbye, World Copy : Hello, World Referenced: Goodbye, World
val src = "Hello" // Its actually not a copy but a reference // That is not a problem because String is immutable // In fact its a feature val des = src assert(src eq des) // Proves the same reference is used. // To make a real copy makes no sense. // Actually its hard to make a copy, the compiler is too smart. // mkString, toString makes also not a real copy val cop = src.mkString.toString assert((src eq cop)) // Still no copyed image val copy = src.reverse.reverse // Finally double reverse makes a copy assert(src == copy && !(src eq copy))// Prove, but it really makes no sense.(define dst (string-copy src))In sed, there are two distinct locations for storing a string: The "pattern space" and the "hold space". The h command copies pattern space to hold space. The g command copies hold space to pattern space.
var string: dest is ""; dest := "Hello";(* In SenseTalk, assignments normally always make copies of values. *) put "glorious" into myWord put myWord into yourWord (* Assignments can also be made by reference if desired. *) put a reference to myWord into myRef set another to refer to myRef put "ly" after myWord put "in" before another put "myWord: " & myWord put "yourWord: " & yourWord put "myRef: " & myRef put "another: " & another- Output:
myWord: ingloriously yourWord: glorious myRef: ingloriously another: ingloriously
src: 'hello' cpy: srcvar original = "hello"; # new String object var reference = original; # points at the original object var copy1 = String.new(original); # creates a new String object var copy2 = original+''; # ==//==BEGIN TEXT ORIGINAL, REFERENCE, COPY1; ORIGINAL :- "THIS IS CONSTANT TEXT"; ORIGINAL.SETPOS(1); REFERENCE :- ORIGINAL; ! RUN TIME ERROR: ! ORIGINAL.PUTCHAR('X'); ! "copy-a-string.sim", line 9: ./copy-a-string: Putchar: Constant text object ; OUTTEXT(ORIGINAL); OUTIMAGE; ! CONTENT EQUAL? => T ; OUTTEXT(IF ORIGINAL = REFERENCE THEN "T" ELSE "F"); OUTIMAGE; ! SAME TEXT OBJECT? => T ; OUTTEXT(IF ORIGINAL == REFERENCE THEN "T" ELSE "F"); OUTIMAGE; COPY1 :- COPY(ORIGINAL); COPY1.SETPOS(1); COPY1.PUTCHAR('X'); OUTTEXT(COPY1); OUTIMAGE; END;- Output:
THIS IS CONSTANT TEXT T T XHIS IS CONSTANT TEXT
[ | :s | s == s copy] applyTo: {'hello'}. "returns False"|s1 s2| "bind the var s1 to the object string on the right" s1 := 'i am a string'. "bind the var s2 to the same object..." s2 := s1. "bind s2 to a copy of the object bound to s1" s2 := (s1 copy).* copy a to b b = a = "test" output = a output = b * change the copy b "t" = "T" output = b end- Output:
test test Test
In Standard ML, strings are immutable, so you don't copy it.
Instead, maybe you want to create a CharArray.array (mutable string) from an existing string:
val src = "Hello"; val srcCopy = CharArray.array (size src, #"x"); (* 'x' is just dummy character *) CharArray.copyVec {src = src, dst = srcCopy, di = 0}; src = CharArray.vector srcCopy; (* evaluates to true *)or from another CharArray.array:
val srcCopy2 = CharArray.array (CharArray.length srcCopy, #"x"); (* 'x' is just dummy character *) CharArray.copy {src = srcCopy, dst = srcCopy2, di = 0};Just use assignment:
var src = "Hello" var dst = srcStrings in Swift are value types, so assigning copies the string.
As strings are immutable, string functions return a new string if changed, and the reference otherwise.
s =: "hello" print s.Usecount t =: s \ reference copy print s.Usecount u =: string (s _ 'x') clip upto -2 print (quote u), u.Usecount, s.Usecount- Output:
1 2 "hello" 1 2
set src "Rosetta Code" set dst $srcTcl copies strings internally when needed. Strings are immutable, but will be copied as part of another string expression. Otherwise it creates references to save memory.
set A "a string" set B $A ; # B is a reference to the string Set C "$A" ; # a new string is created set D "This is $C" ; # the string bound to C is copied into a new string. # the append command is internally optimized # for adding to the end of a string or list # as is string index for returning a letter # reverse a string proc reverse {s} { set len [string length $s] set r "" for { set i $len} { $i >= 0} {incr i -1} { append r [string index $s $i] } return $r } set a 12345 set b [reverse $a] puts stdout "b: $b"54321
Copy/Replace
# replace substrings in a string set rep [string map {"apple" "orange"} "I like apples."] puts stdout $repI like oranges.
:"Rosetta Code"→Str1 :Str1→Str2:"Rosetta Code"→str1 :str1→str2" hello" is-data a a string.clone is-data b#lang transd MainModule : { _start: (λ (with s "Hello!" s1 "" s2 "" (= s1 s) // duplication of 's' content (rebind s2 s) // another reference to 's' (= s "Good bye!") (lout s) (lout s1) (lout s2) ) ) }- Output:
Good bye! Hello! Good bye!
Strings are immutable character sequences, so copying a string just means duplicating the reference at the top of the stack:
"Hello" dup$$ MODE TUSCRIPT str="Hello" dst=strCopies contents of string.
."hello" first
- Output:
"hello" @h
foo="Hello" bar=$foo # This is a copy of the stringdecl string a b set a "hello" set b adup really makes a reference, but the language is functional, so the string is immutable.
"hello" dupThis program copies string in variable a to variable b. Mutating variable a subsequently doesn't alter variable b. Variable b is not a reference.
Sub copystring() a = "Hello World!" b = a a = "I'm gone" Debug.Print b Debug.Print a End Sub- Output:
Hello World! I'm gone
let str1 = "original string" let str2 = str1 let str1 = "new string" echo "String 1:" str1 echo "String 2:" str2- Output:
String 1: new string String 2: original string
Platform: .NET
'Immutable Strings Dim a = "Test string" Dim b = a 'reference to same string Dim c = New String(a.ToCharArray) 'new string, normally not used 'Mutable Strings Dim x As New Text.StringBuilder("Test string") Dim y = x 'reference Dim z = New Text.StringBuilder(x.ToString) 'new stringAlternatively, you can use, with all versions of the .NET framework:
Dim a As String = "Test String" Dim b As String = String.Copy(a) ' New stringStrings in Vlang are immutable. There is no need to distinguish between copying and making an additional reference.
text := "Hello" copy_of := text println(copy_of)- Output:
Hello
A string in Wren is an immutable array of bytes.
Although technically a reference type, this means there is no need to distinguish between copying the contents of a string and making an additional reference. We can therefore just use assignment to copy a string.
var s = "wren" var t = s System.print("Are 's' and 't' equal? %(s == t)")- Output:
Are 's' and 't' equal? true
creating a second 0 terminated string with the same content:
section .data string db "Hello World", 0 section .bss string2 resb 12 section .text global _main _main: mov ecx, 0 looping: mov al, [string + ecx] mov [string2 + ecx], al inc ecx cmp al, 0 ;copy until we find the terminating 0 je end jmp looping end: xor eax, eax retcreating a second string; first byte signals length of string
section .data string db 11,"Hello World" section .bss string2 resb 12 section .text global _main _main: xor ecx, ecx ;clear ecx mov cl, [string] mov [string2], cl ;copy byte signaling length mov edx, 1 looping: ;copy each single byte mov al, [string + edx] mov [string2 + edx], al inc edx dec ecx cmp ecx, 0 jg looping xor eax, eax retUASM 2.52
option casemap:none option literals:on printf proto :dword, :VARARG exit proto :dword .data s db "Goodbye, World!",0 .data? d db 20 dup (?) dp dq ? tb dd ? .code main proc lea rsi, s ;; Put the address of var S into the source index(RSI) xor rcx, rcx ;; Zero out RCX _getsize: inc rcx ;; Advanced the index by 1 cmp byte ptr [rsi+rcx],0 ;; check the current byte for terminating 0 jne _getsize ;; nope, jump back and check again mov tb, ecx ;; tb = Total bytes, Keep a copy of the size of the string lea rsi, s ;; Copy the address of s into the source index(rsi) lea rdi, d ;; Copy the address of d into the destination index(rdi) rep movsb ;; Copy bytes from ESI to EDI until RCX is 0 lea rax, s ;; Get the address of S mov dp, rax ;; Copy it from RAX to dp mov rbx,rdi ;; Make a copy of RDI, cause over writes due to ABI call args T_T invoke printf, CSTR("-> s (0x%x) = %s",10), rsi, addr s invoke printf, CSTR("-> d (0x%x) = %s",10), rbx, addr d invoke printf, CSTR("-> dp (0x%x) = %s",10), addr dp, dp invoke printf, CSTR("-> bytes copied: %i",10), tb xor rsi, rsi call exit ret main endp end- Output:
-> s (0x40303f) = Goodbye, World! -> d (0x40309f) = Goodbye, World! -> dp (0x4030a4) = Goodbye, World! -> bytes copied: 15
NASM 2.15
%macro sysdef 2 %define sys_%1 %2 %endmacro sysdef write, 1 %macro prolog 1 push rbp mov rbp, rsp sub rsp, %1 %endmacro %macro epilog 1 add rsp, %1 pop rbp %endmacro %macro xlea 2 lea %1, [rel %2] %endmacro %macro inv 1-7 0,0,0,0,0,0 mov r9,%7 mov r8,%6 mov r10,%5 mov rdx,%4 mov rsi,%3 mov rdi,%2 mov rax,sys_%1 syscall %endmacro section .rodata sz1 db "Goodbye, World!",0xa,0 section .bss sz2 resq 1 section .text strlcpy: prolog 0x38 %define dest rbp-0x18 %define src rbp-0x10 %define n rbp-0x8 mov qword [rbp-0x28], rdi mov qword [rbp-0x30], rsi mov qword [rbp-0x38], rdx mov rax, qword [rbp-0x28] mov qword [dest], rax mov rax, qword [rbp-0x30] mov qword [src], rax mov rax, qword [rbp-0x38] mov qword [n], rax cmp qword [n], 0 je _stlc_done _stlc_doloop: dec qword [n] cmp qword [n], 0 je _stlc_done mov rbx, qword [src] lea rax, [rbx+1] mov qword [src], rax mov rax, qword [dest] lea rcx, [rax+1] mov qword [dest], rcx movzx ebx, byte [rbx] mov byte [rax], bl movzx eax, byte [rax] test al, al je _stlc_done jmp _stlc_doloop _stlc_done: epilog 0x38 ret strlen: prolog 0x10 %define s rbp-0x8 mov qword [rbp-0x10], rdi mov rax, qword [rbp-0x10] mov qword [s], rax mov rsi, qword [s] xor rcx, rcx _stl_count: cmp byte [rsi+rcx], 0 je _stl_exit inc rcx jne _stl_count _stl_exit: mov rax, rcx epilog 0x10 ret global main main: prolog 0x20 %define tmp rbp-0x20 xlea rbx, sz1 mov qword [tmp], rbx mov rdi, qword [tmp] call strlen mov rcx, rax push rcx mov rdx, rcx xlea rsi, sz1 xlea rdi, sz2 call strlcpy xlea rbx, sz2 pop rcx inv write, 1, rbx, rcx inv exit, 0 epilog 0x20 ret- Output:
Goodbye, World!
The default method of terminating strings is to set the most significant bit of the last character. An alternative is to use the 'string 0' command to specify zero-terminated strings. The string copy routine from the standard library is shown.
proc StrCopy(A, B); \Copy string: A --> B char A, B; \Strings: B must already have enough space "Reserved" int I; \Beware if strings overlap for I:= 0 to -1>>1-1 do [B(I):= A(I); if A(I) >= $80 then return ]; char S1, S2, S3(13); [S1:= "Hello, world!"; \S1 now points to the string S2:= S1; \S2 now also points to the string StrCopy(S1, S3); \S3 points to a separate copy of the string ]%\n { 0a } %\0 { 00 } |18 @Console/write |100 ;str2 ;str1 copy-str ;str2 print-str BRK @copy/str ( dest* src* -: ) STH2 &loop LDAkr STH2k STAr INC2 LDAkr STHr INC2r ?/loop POP2 POP2r JMP2r @print/str_ ( str* -: ) LDAk .Console/write DEO INC2 @print/str LDAk ?/str_ POP2 JMP2r @str1 "Uxntal \n \0 @str2- Output:
Uxntal
Making An Additional Reference
Making an additional reference to a string is easy. If you know the address of the beginning of the string, store that address in RAM somewhere else.
ld hl,MyString ld (PointerVariable),hl MyString: ;assembler equates this label to a memory location at compile time byte "Hello",0 PointerVariable: word 0 ;placeholder for the address of the above string, gets written to by the code above.NOTE: If you're programming for the Game Boy, you can't store a 16-bit value directly into RAM from HL. There are other methods to achieve the same result, and here's one:
ld a,<MyString ; < represents the low byte of the address. Some assemblers use LOW() with the label in the parentheses. ld (PointerVariable),a ld a,>MyString ; > represents the high byte of the address. Some assemblers use HIGH() with the label in the parentheses. ld (PointerVariable+1),aCopying A String
As long as you have enough RAM space to hold the entire string, you can copy it somewhere else in memory. If you know the string's length in advance a simple LDIR will be sufficient. This method will use the null terminator to tell the copy function when to stop:
StrCpy: ;input: HL = base address of string you wish to copy ; DE = where you want to copy it to. ; This program assumes that the string is null-terminated, and that there is enough RAM to hold the entire string. ld a,(hl) or a ;compare A to 0. ret z ld (de),a inc hl inc de jr StrCpyIf you're using the "Pascal style" where the string length is prepended before the string itself, you can use this method instead, assuming your string is shorter than 255 bytes in length.
ld hl,myString ld c,(hl) ld b,0 inc c ld de,buffer ldir ;copies from (HL) to (DE), BC times. ret myString: byte 5 ;len("Hello") byte "Hello" buffer: byte 0 byte 0,0,0,0,0const std = @import("std"); const debug = std.debug; const mem = std.mem; test "copy a string" { const source = "A string."; // Variable `dest1` will have the same type as `source`, which is // `*const [9:0]u8`. const dest1 = source; // Variable `dest2`'s type is [9]u8. // // The difference between the two is that `dest1` string is null-terminated, // while `dest2` is not. var dest2: [source.len]u8 = undefined; mem.copy(u8, dest2[0..], source[0..]); debug.assert(mem.eql(u8, dest1[0..], "A string.")); debug.assert(mem.eql(u8, dest2[0..], "A string.")); }Strings are immutable so copy is just return the string:
"abc".copy() // noopmodule Main; var s,r: string; c: array 60 of char; begin s := "plain string";r := s; writeln(s); (* copy string to array of char *) copy(s,c);c[0] := 'P'; (* copy array of char to string *) copy(c,r);writeln(r); end Main.For typing:
var a var b a = "World" b = a a = "Hello" print (a," ",b)For importing:
¶0¶var a¶0¶var b¶0¶a = "World"¶0¶b = a¶0¶a = "Hello"¶0¶print (a," ",b)
10 LET a$ = "Hello": REM a$ is the original string 20 LET b$ = a$: REM b$ is the copyVersion 1: Assign variable "s" to variable "b".
#include <hopper.h> main: s = "string to copy" t = s {s,"\n",t}println exit(0)Output:
string to copy string to copy
Version 2: Soft copy to variable (CPY).
#include <hopper.h> main: s="" {"1:","string to copy"},cpy(s),println {"2:",s}println exit(0)Output:
1:string to copy 2:string to copy
Version 3: From stack to var: hard copy (move, MOV).
#include <hopper.h> main: s="" {"string to copy"},mov(s) {s}println exit(0)Output:
string to copy