In programming we call any text a `String` regardless of whether it consists of a single character, a word, or a big block of text. A `String` is basically a sequence of characters of unspecified size that usually ends with the \0 character (character whose ASCII code is 0). In Alusus there are two ways to define a String:
This class simplifies dealing with strings since it takes the responsibility of allocating and releasing the memory for the string while taking into account the performance and avoiding unnecessary operations like copying and allocating memory. Also, it contains many helper methods, and it exists in Standard Runtime Library `Srl`, which means we must import it before using this class.
Importing and defining a String variable can be done like this:
import "Srl/String.alusus"; // first we import this class def string_name: String = "Initial Value"; // define a string
Where the initial value is an optional initial value for the variable `string_name`, and we should remember to enclose the string in double quotes.
Example:
Define and print a string in different ways.
import "Srl/Console.alusus"; import "Srl/String.alusus"; use Srl; def str: String="Alusus"; Console.print(str); // Alusus // In case you want to print it with some explanatory sentences, you can do that as follows: Console.print(String("language: ") + str); // language: Alusus // You can also execute the print operation in the following way using the placeholder `s` Console.print("language: %s", str.buf); // language: Alusus
Note that in this case we use the property `buf` to get a pointer to the string buffer because the print function (which uses libc's printf function) expects C lang strings (i.e. pointer to characters), not an object of type `String`.
You can receive a string from the user by creating an array of chars and using `getString` function in the `Console` module.
Example:
An Alusus program to show a string entered by the user.
import "Srl/Console.alusus" import "Srl/String.alusus"; use Srl; def str: String; // define a string def s: array[Char, 100]; // an array of characters with specific size for input purposes Console.print("Enter a string: "); Console.getString(s~ptr, 100); // we pass a pointer to the array with its size str=s~ptr; // now the characters are copied from the array to the string object Console.print(String("You entered: ") + str + String("\n")); /* Enter a string: Hello World! You entered: Hello World! */
It means adding one string to another, which is done by putting the strings beside each other. For example:
import "Srl/Console.alusus"; import "Srl/String.alusus"; use Srl; def firstName: String = "Ali"; def lastName: String = "Ahmad"; def fullName: String; fullName = firstName + " " + lastName; Console.print(String("fullName: ") + fullName); // fullName: Ali Ahmad
Strings are stored in memory character by character and in order. When defining a variable of type `String` an initial memory is allocated for the variable. This memory is increased automatically when necessary. Note the following example:
import "Srl/Console.alusus"; import "Srl/String.alusus"; use Srl; def str: String = "Language "; // here a memory is allocated for the string str += "Alusus" // here the memory is increased
The number of characters in the string represents the length of the string and we can know that by using `getLength` function. It is also possible to access any character in the string by putting its index enclosed in parentheses after the string name.
Example:
import "Srl/Console.alusus"; import "Srl/String.alusus"; use Srl; def firstName: String = "Ali"; def lastName: String = "Ahmad"; def fullName: String; fullName = firstName+ " " + lastName Console.print(String("fullName: ") + fullName+String("\n")) // fullName: Ali Ahmad Console.print(String("Length: ") + fullName.getLength()+String("\n")) // Length: 9 Console.print(String("Character: ") + fullName(5)) // Character: h
English characters are stored using 1 byte for each character, whereas other languages, like Arabic, needs 2 or more bytes for each character. For example, the string "اب" needs 4 bytes, whereas the string "ab" needs 2 bytes only.
Note: The encoding used in the strings is "UTF-8" and the difference in number bytes between English and other languages is determined by "UTF-8", not Alusus.
We can use operators like ==, !=, <, >, <=, >= to compares strings.
Example:
import "Srl/Console.alusus"; import "Srl/String.alusus"; use Srl; def str1: String="Alusus"; def str2: String="Language"; // the two strings are the identical if (str1 == str2) Console.print("str1 == str2\n"); // the two strings are different if (str1 != str2) Console.print("str1 != str2\n"); // the first string is after the second one in the dictionary order. if (str1 > str2) Console.print("str1 > str2\n"); if (str1 >= str2) Console.print("str1 >= str2\n"); if (str1 < str2) Console.print("str1 < str2\n"); if (str1 <= str2) Console.print("str1 <= str2\n"); /* str1 != str2 str1 < str2 str1 <= str2 */
Notes:
We will give some examples of the most important methods of this class. You can view all its methods here.
- We use `find` function to execute the following search operations in the strings:
Example:
import "Srl/Console.alusus"; import "Srl/String.alusus"; use Srl; def str: String = "Alusus language properly deals with memory"; // here we print the first index that contains the letter 'u' in this string `str'. Console.print("%d\n", str.find('u')); // 2 // here we print the index at which the string "language" is found (the index of its first letter). Console.print("%d\n", str.find("language")); // 7
- We use `findLast` function in a way similar to the previous function but the search operation starts from the end of the string.
Example:
import "Srl/Console.alusus"; import "Srl/String.alusus"; use Srl; def str: String="Alusus language is based on the C language"; def keyword: char = 's'; // Find first occurrence of 's' if (str.find(keyword) != -1) { Console.print("First occurrence is %d\n",str.find(keyword)); // First occurrence is 3 } // Find the last occurrence of 's' if (str.findLast(keyword) != -1) { Console.print("Last occurrence is %d\n",str.findLast(keyword)); // Last occurrence is 21 }
- You can use `append` function to execute the following operations:
In all previous cases, the modification is done directly on the string that call these functions.
Example:
import "Srl/Console.alusus"; import "Srl/String.alusus"; use Srl; def str1: String = "Alusus language is compatible with "; def str2: String = "the C language."; str1.append(str2); // add the second string to the first Console.print(String("Adding str2 to str1: ") + str1); /* Adding str2 to str1: Alusus language is compatible with the C language. */
Note: It is also possible to use `+=` operator instead of this function.
- You can use `concat` function in a similar way to `append` function with a small difference which is that this function returns the result in a new string instead
of modifying the current string.
Example:
import "Srl/Console.alusus"; import "Srl/String.alusus"; use Srl; def str1: String = "Alusus language is based on "; def str2: String = "the C language."; def str: String; str = str1.concat(str2); // add the second string to the first one Console.print(String("Adding str2 to str1 and storing the result in str: ") + str);
Note: It is also possible to use `+` operator instead of this function.
- You can use `compare` function to do comparison between strings (dictionary order).
Example:
import "Srl/Console.alusus"; import "Srl/String.alusus"; use Srl; def str1: String = "Alusus language is compatible with "; def str2: String = "the C language."; Console.print("%d\n", str1.compare(str2)); Console.print("%d\n", str1.compare(str1)); Console.print("%d\n", str2.compare(str1)); /* -51 0 51 */
- You can use `replace` function to modify a specific from the string "Substring" which called it (modification is not on the same string, instead it
is done on a copy). We pass to it the substring we want to remove and the string we want to replace it with.
Example:
We will replace the word "language" with "*" in the following:
import "Srl/Console.alusus"; import "Srl/String.alusus"; use Srl; def str1: String = "Alusus language is compatible with the C language."; def str2 : String; str2=str1.replace("language","*"); Console.print(str2) /* Alusus * is compatible with the C *. */
- You can change the case of letters from upper to lower or the opposite, using `toLowerCase` and `toUpperCase` functions (the modification is done on a copy).
import "Srl/Console.alusus"; import "Srl/String.alusus"; use Srl; def str: String = "Alusus language is compatible with the C language.\n"; str = str.toUpperCase(); Console.print(str); str = str.toLowerCase(); Console.print(str); /* ALUSUS LANGUAGE IS COMPATIBLE WITH THE C LANGUAGE. alusus language is compatible with the c language. */
- You can use `split` function to split a string into multiple parts based on a specific character (or a string), and this function returns an array of the
strings.
Example:
import "Srl/Console"; import "Srl/String"; import "Srl/Array"; use Srl; def str: String = "Alusus language is compatible with the C language."; def arr: Array[String]; arr = str.split(" "); // splitting the string into words and store it in array def index: Int; for index = 0, index < arr.getLength(), index++ { Console.print("The value of element %d is: %s\n", index, arr(index).buf); } /* The value of element 0 is: Alusus The value of element 1 is: language The value of element 2 is: is The value of element 3 is: compatible The value of element 4 is: with The value of element 5 is: the The value of element 6 is: C The value of element 7 is: language. */
- You can use `slice` function to copy (or cut) a part from the string and store it in a new string without modifying the original string since the
function returns the part ("Substring") as new string. We pass to this function the index of the character we want to start copying from it and the
number of characters we want to copy.
Example:
import "Srl/Console.alusus"; import "Srl/String.alusus"; use Srl; def str: String="Alusus language is compatible with the C language."; def substring: String; substring = str.slice(7, 8); Console.print(substring); /* language */
We can use this type to define a string. To access the characters of this string we will user the operator `~cnt`
because the variable is a pointer and we want to access the content it points to, which is what this operator does.
Example 1:
import "Srl/Console.alusus" use Srl.Console; def s: ptr[array[Char]] = "Alusus"; // define a string print("Lannguage: %s\n", s); // print it print("First character: %c\n", s~cnt(0)); // accessing the first item and print it print("Second one: %c\n", s~cnt(1)); // accessing the second item and print it print("ASCII of A: %d",s~cnt(0)); // print the value of the first item in ASCII /* Lannguage: Alusus First character: A Second one: l ASCII of A: 65 */
Example 2:
An Alusus program to show a string entered by the user.
import "Srl/Console.alusus" use Srl.Console; def s: ptr[array[Char]]; def input: array[Char, 100]; // define an array of chars for input print("Enter a string: "); getString(input~ptr, 100); s = input~ptr; print("You entered : %s\n",s) // print it /* Enter a string: Alusus Language You entered : Alusus Language */
- Generally, using `String` class is easier, more flexible, and safer. Also, it contains many helper methods, and it can be used instead of
`ptr[array[Char]]` so it is better to use it. But sometimes, we may need to deal with C libraries and functions, in that case we need to deal with
this type (it is compatible with char* in C).
- The type `ptr[array[Char]]` is compatible with `char *` in C as we mentioned, so it is useful to deal with the system libraries and functions.
- When dealing with this type it is hard to use the strings dynamically because we need to allocate the memory and release it manually, whereas in
`String` class these operations are done easily and automatically.
- The size of the string is fixed since the size of the characters buffer is predetermined and you can not change it unless you allocate another
memory dynamically and manually, so changing the string by removing or adding an item becomes complicated.
Note that in the previous example we defined a variable `s` with type `ptr[array[Char]]` and then we defined an array of chars `input` with size 100
for input operation, so the entered string must be no longer than 100 characters.