33. String Class
Learn the basic usage of the String
class.
33.1 String
- In Siv3D, strings are represented using the
String
type
String
is an array of char32
type (characters) that represent UTF-32 code points
- UTF-32 character and string literals are prefixed with
U
, like U'あ'
and U"Hello"
String
uses std::u32string
internally to manage strings
- The following is guaranteed for the stored string data:
- String data is contiguous in memory
- There is a null character
U'\0'
immediately after the last element of the string
- It has more member functions than C++ standard library string classes and provides various convenient features
String s1 = U"Siv3D";
String s2 = U"こんにちは、Siv3D!";
33.2 String Creation
String
is created using the following methods:
- Create empty string
- Create string from string literal
- Create string with count × character
# include <Siv3D.hpp>
void Main()
{
{
// Create empty string
String s;
Print << s;
}
{
// Create string from string literal
String s = U"Siv3D";
Print << s;
}
{
// Create string with count × character
String s(5, U'A');
Print << s;
}
while (System::Update())
{
}
}
33.3 String Length
.size()
returns the length (number of elements) of the string as size_t
type
- String length is the number of UTF-32 code points represented by
char32
type
- Most characters like alphabets, hiragana, and kanji are 1 character = 1 code point
- Some special characters like certain emoji may consist of multiple code points even though they appear as 1 character
# include <Siv3D.hpp>
void Main()
{
{
String s = U"Siv3D";
Print << s.size();
}
{
String s = U"こんにちは";
Print << s.size();
}
{
String s = U"🐈";
Print << s.size();
}
{
// Some emoji consist of multiple code points
String s = U"👩🎤";
Print << s.size();
}
while (System::Update())
{
}
}
33.4 Checking if Empty (1)
.isEmpty()
returns whether the string is empty (has 0 elements) as bool
type
# include <Siv3D.hpp>
void Main()
{
String s1 = U"Siv3D";
Print << s1.isEmpty();
String s2;
Print << s2.isEmpty();
while (System::Update())
{
}
}
33.5 Checking if Empty (2)
- Use
if (s)
to check if a string is empty
- If the string is empty, it evaluates to
false
# include <Siv3D.hpp>
void Main()
{
String s1 = U"Siv3D";
if (s1)
{
Print << U"s1 is not empty";
}
String s2;
if (not s2)
{
Print << U"s2 is empty";
}
while (System::Update())
{
}
}
Outputs1 is not empty
s2 is empty
33.6 Adding Elements to End
s << ch;
adds element ch
to the end of string s
- This is a shorthand for
.push_back(ch)
- Adding to the end of a string is the most efficient compared to adding to other locations (beginning or middle)
# include <Siv3D.hpp>
void Main()
{
String s;
s << U'S';
s << U'i';
s << U'v';
Print << s;
s << U'3' << U'D';
Print << s;
while (System::Update())
{
}
}
33.7 Removing Last Element
.pop_back()
removes the last element of the string
- Must not be called when the number of elements is 0
- Check that the number of elements is not 0 beforehand
- Removing the last element of a string is the most efficient compared to removing from other locations (beginning or middle)
# include <Siv3D.hpp>
void Main()
{
String s = U"Siv3D";
Print << s;
s.pop_back();
Print << s;
s.pop_back();
Print << s;
while (s)
{
s.pop_back();
}
Print << s.isEmpty();
while (System::Update())
{
}
}
OutputSiv3D
Siv3
Siv
true
33.8 Removing All Elements
.clear()
removes all elements from the string, making it an empty string
- Can be called when the number of elements is 0 (does nothing)
# include <Siv3D.hpp>
void Main()
{
String s = U"Siv3D";
Print << s;
s.clear();
Print << s.isEmpty();
while (System::Update())
{
}
}
33.9 Changing Number of Elements
.resize(n)
changes the number of elements in the string to n
- When the number of elements increases, new elements are initialized with null character U'\0', so they need to be overwritten with other characters
# include <Siv3D.hpp>
void Main()
{
String s = U"Siv3D";
Print << s;
s.resize(3);
Print << s;
s.resize(5);
s[3] = U'!';
s[4] = U'?';
Print << s;
while (System::Update())
{
}
}
33.10 Array Traversal with Range-for Loop (const reference)
- Use range-for loops to traverse array elements
- Element access is usually done with const references
- Do not perform operations that change the size of the target string within the range-for loop
# include <Siv3D.hpp>
void Main()
{
String s = U"Siv3D";
for (const auto& ch : s)
{
Print << ch;
}
while (System::Update())
{
}
}
33.11 Array Traversal with Range-for Loop (reference)
- Use range-for loops to traverse array elements
- When modifying elements within the loop, use references instead of const references to access elements
- Do not perform operations that change the size of the target string within the range-for loop
# include <Siv3D.hpp>
void Main()
{
String s = U"Siv3D";
for (auto& ch : s)
{
++ch;
}
Print << s;
while (System::Update())
{
}
}
33.12 Accessing Elements at Specified Index
[i]
accesses the i
-th element of the string
i
is counted from 0. Valid indices are from 0 to size() - 1
- Must not access out of range
# include <Siv3D.hpp>
void Main()
{
String s = U"Siv3D";
Print << s[0];
Print << s[4];
s[3] = U'4';
Print << s;
while (System::Update())
{
}
}
33.13 Accessing First and Last Elements
.front()
returns a reference to the first element
.back()
returns a reference to the last element
- Must not be called when the number of elements is 0
# include <Siv3D.hpp>
void Main()
{
String s = U"Siv3D";
Print << s.front();
Print << s.back();
s.front() = U's';
s.back() = U'd';
Print << s;
while (System::Update())
{
}
}
33.14 Creating String by Concatenating Two Strings
s1 + s2
creates a new string by concatenating strings s1
and s2
s1
and s2
are not modified
# include <Siv3D.hpp>
void Main()
{
String s1 = U"Hello, ";
String s2 = U"Siv3D!";
Print << (s1 + s2);
Print << (s1 + s2 + U"!!!");
while (System::Update())
{
}
}
OutputHello, Siv3D!
Hello, Siv3D!!!!
33.15 Adding String to End
+=
adds a string to the end of the string
# include <Siv3D.hpp>
void Main()
{
String s = U"Hello, ";
s += U"Siv3D!";
Print << s;
s += U"!!!";
Print << s;
while (System::Update())
{
}
}
OutputHello, Siv3D!
Hello, Siv3D!!!!
33.16 Getting Iterators for Beginning and End Positions
.begin()
returns an iterator to the beginning position
.end()
returns an iterator to the end position
# include <Siv3D.hpp>
void Main()
{
String s = U"Siv3D";
auto it = s.begin();
Print << *it;
++it;
Print << *it;
while (System::Update())
{
}
}
33.17 Other Insert and Delete Operations
.push_front(value)
adds an element to the beginning
.pop_front()
removes the first element
.insert(iterator, value)
inserts an element at the specified iterator position
.erase(iterator)
removes the element at the specified iterator position
.erase(iterator1, iterator2)
removes elements in the specified range
- Inserting/deleting elements at the beginning or middle involves moving subsequent existing elements, so the cost is proportional to the number of elements after
- Should normally be avoided or used only with small strings
# include <Siv3D.hpp>
void Main()
{
{
String s = U"Siv3D";
s.push_front(U'#');
Print << s;
s.pop_front();
Print << s;
}
{
String s = U"Siv3D";
s.insert((s.begin() + 3), U'#');
Print << s;
}
{
String s = U"Siv3D";
s.erase(s.begin() + 3);
Print << s;
s.erase(s.begin(), (s.begin() + 2));
Print << s;
}
while (System::Update())
{
}
}
Output#Siv3D
Siv3D
Siv#3D
SivD
vD
33.18 Checking if Contains Character or String
.contains(character)
returns whether the string contains the specified character as bool
type
.contains(string)
returns whether the string contains the specified string as bool
type
# include <Siv3D.hpp>
void Main()
{
String s = U"Hello, Siv3D!";
Print << s.contains(U'S');
Print << s.contains(U'i');
Print << s.contains(U'4');
Print << s.contains(U"3D");
Print << s.contains(U"Hello");
Print << s.contains(U"Hi");
while (System::Update())
{
}
}
Outputtrue
true
false
true
true
false
33.19 Checking if Starts With or Ends With Character or String
.starts_with(character)
returns whether the string starts with the specified character as bool
type
.starts_with(string)
returns whether the string starts with the specified string as bool
type
.ends_with(character)
returns whether the string ends with the specified character as bool
type
.ends_with(string)
returns whether the string ends with the specified string as bool
type
# include <Siv3D.hpp>
void Main()
{
String s = U"Hello, Siv3D!";
Print << s.starts_with(U'H');
Print << s.starts_with(U'S');
Print << s.starts_with(U"Hello");
Print << s.starts_with(U"Hi");
Print << s.ends_with(U'!');
Print << s.ends_with(U'D');
Print << s.ends_with(U"3D!");
Print << s.ends_with(U"Hi");
while (System::Update())
{
}
}
Outputtrue
false
true
false
true
false
true
false
33.20 Creating Substrings
.substr(start_position, length)
creates a substring of length
characters starting from start_position
in the string as a new String
start_position
starts from 0
- If
length
is omitted, a substring from the start_position
character to the end is created
- If
length
is larger than the actual string length, a substring exactly to the end is created
# include <Siv3D.hpp>
void Main()
{
const String s = U"Hello, Siv3D!";
Print << s.substr(0, 5);
Print << s.substr(7, 3);
Print << s.substr(7);
Print << s.substr(0, 100);
while (System::Update())
{
}
}
OutputHello
Siv
Siv3D!
Hello, Siv3D!
- This can be applied to programs that display strings over time as follows:
# include <Siv3D.hpp>
void Main()
{
const String s = U"Hello, Siv3D!";
Stopwatch stopwatch{ StartImmediately::Yes };
while (System::Update())
{
ClearPrint();
const int32 count = (stopwatch.ms() / 300);
Print << s.substr(0, count);
}
}
33.21 Converting Alphabets to Lowercase/Uppercase
.lowercased()
creates a new string with alphabets converted to lowercase
.uppercased()
creates a new string with alphabets converted to uppercase
# include <Siv3D.hpp>
void Main()
{
const String s = U"こんにちは、Siv3D!";
// Create new string with lowercase
Print << s.lowercased();
// Create new string with uppercase
Print << s.uppercased();
while (System::Update())
{
}
}
Outputこんにちは、siv3d!
こんにちは、SIV3D!
33.22 Reversing String
.reversed()
creates a new string with the string reversed
- The original string is not modified
.reverse()
reverses the string
- The original string is modified
# include <Siv3D.hpp>
void Main()
{
const String s1 = U"Hello, Siv3D!";
// Create new string with reversed order
Print << s1.reversed();
String s2 = U"Hello, Siv3D!";
// Reverse the string
s2.reverse();
Print << s2;
while (System::Update())
{
}
}
Output!D3viS ,olleH
!D3viS ,olleH
33.23 Shuffling String Elements
.shuffled()
creates a new string with the string elements shuffled
- The original string is not modified
.shuffle()
shuffles the string elements
- The original string is modified
# include <Siv3D.hpp>
void Main()
{
const String s1 = U"Hello, Siv3D!";
// Create new string with shuffled elements
Print << s1.shuffled();
String s2 = U"Hello, Siv3D!";
// Shuffle string elements
s2.shuffle();
Print << s2;
while (System::Update())
{
}
}
Example Outputvel SDH!,loi3
3 lo!vl,SHDie
33.24 Character and String Replacement
.replaced(from, to)
creates a new string with from
replaced by to
in the string
- The original string is not modified
.replace(from, to)
replaces from
with to
in the string
- The original string is modified
# include <Siv3D.hpp>
void Main()
{
String s = U"Hello, Siv3D!";
// Create new string with Siv3D replaced by C++
Print << s.replaced(U"Siv3D", U"C++");
// Replace ! with ?
s.replace(U'!', U'?');
Print << s;
// Create new string with Hello replaced by Hi
Print << s.replaced(U"Hello", U"Hi");
while (System::Update())
{
}
}
OutputHello, C++!
Hello, Siv3D?
Hi, Siv3D?
33.25 Removing Leading and Trailing Whitespace
.trimmed()
creates a new string with whitespace characters (spaces, tabs, newlines, etc.) removed from the beginning and end of the string
- The original string is not modified
.trim()
removes whitespace characters from the beginning and end of the string
- The original string is modified
# include <Siv3D.hpp>
void Main()
{
String s1 = U" Hello, Siv3D! ";
// Remove leading and trailing whitespace
s1.trim();
Print << s1;
Print << s1.size();
const String s2 = U"\n\n Siv3D \n\n\n";
// Create new string with leading and trailing whitespace removed
Print << s2.trimmed();
while (System::Update())
{
}
}
OutputHello, Siv3D!
13
Siv3D
33.26 Splitting by Specified Character
.split(delimiter)
returns the result of splitting the string by delimiter
as Array<String>
delimiter
is a single character string
- If
delimiter
appears consecutively, empty strings are generated
- If
delimiter
appears at the beginning or end of the string, empty strings are generated
- If
delimiter
is not contained in the string, the original string is returned as is
# include <Siv3D.hpp>
void Main()
{
{
const String s = U"red,green,blue";
const Array<String> values = s.split(U',');
Print << values;
}
{
const String s = U",,a,";
const Array<String> values = s.split(U',');
Print << values;
}
{
const String s = U"1, 2, 3, 4, 5";
// Example converting number strings separated by U',' to Array<int32>
const Array<int32> values = s.split(U',').map(Parse<int32>);
Print << values;
}
while (System::Update())
{
}
}
Output{red, green, blue}
{, , a, }
{1, 2, 3, 4, 5}
33.27 Converting to Other String Types
String
has the following member functions to convert to other string types:
Code |
Description |
.narrow() |
Convert to std::string (character encoding is environment-dependent) |
.toUTF8() |
Convert to std::string (UTF-8) |
.toWstr() |
Convert to std::wstring |
.toUTF16() |
Convert to std::u16string |
.toUTF32() |
Convert to std::u32string |
Environment-dependent character encoding
- The character encoding of
std::string
varies by environment
- Japanese Windows uses Shift_JIS (CP932), macOS and Linux use UTF-8
- From Siv3D v0.8 onwards,
std::string
character encoding will be unified to UTF-8
# include <Siv3D.hpp>
void Main()
{
const String s = U"こんにちは、Siv3D!";
const std::string s1 = s.narrow();
const std::string s2 = s.toUTF8();
const std::wstring s3 = s.toWstr();
const std::u16string s4 = s.toUTF16();
const std::u32string s5 = s.toUTF32();
while (System::Update())
{
}
}
- To pass a
String
string to a function that takes const char*
, get the head pointer of the std::string
obtained with .narrow()
using c_str()
:
33.28 Converting from Other String Types
- The following functions convert from other string types to
String
:
Code |
Description |
Unicode::Widen(s) |
Convert from std::string (character encoding is environment-dependent) to String |
Unicode::WidenAscii(s) |
Convert from std::string (ASCII) to String |
Unicode::FromWstring(s) |
Convert from std::wstring to String |
Unicode::FromUTF8(s) |
Convert from std::string (UTF-8) to String |
Unicode::FromUTF16(s) |
Convert from std::u16string to String |
Unicode::FromUTF32(s) |
Convert from std::u32string to String |
# include <Siv3D.hpp>
void Main()
{
const String s1 = Unicode::Widen("こんにちは、Siv3D!");
const String s2 = Unicode::WidenAscii("Hello, Siv3D!");
const String s3 = Unicode::FromWstring(L"こんにちは、Siv3D!");
const String s4 = Unicode::FromUTF8("こんにちは、Siv3D!");
const String s5 = Unicode::FromUTF16(u"こんにちは、Siv3D!");
const String s6 = Unicode::FromUTF32(U"こんにちは、Siv3D!");
while (System::Update())
{
}
}
33.29 FilePath
- To clarify that a string refers to a file path,
FilePath
is provided as an alias for String
# include <Siv3D.hpp>
void Main()
{
FilePath path = U"example/windmill.png";
Print << path;
while (System::Update())
{
}
}
Outputexample/windmill.png