Strings¶
CF has a dynamic string API where strings are 100% compatible with normal C-strings. Dynamic strings can be modified and grow onto the heap as necessary. They come with a wide variety of manipulation functions such as removing certain characters, trimming whitespace, find + replace, and a whole lot more. In C++ we also have the String
class which wraps the dynamic C string API.
Dynamic Strings¶
In CF's C API we can create a new string with sset
.
Or alternatively:
Which outputs:
All dynamic strings must be free'd up with sfree
when done.
To push some more characters onto the end of the string use spush
.
Which outputs:
You can append a string onto the end of a dynamic string with sappend
.
char* s = NULL;
sset(s, "Hello world!");
sappend(s, " What a nice string we have.");
printf("%s", s);
sfree(s);
Which outputs:
String Conversions¶
To convert an integer to a string call sint
.
To convert from a string to an integer call stoint.
There are similar functions available for float, double, boolean, and hex numbers.
String Formatting¶
String formatting is done with a printf-style function called sfmt
.
sfmt(s, "%s said hello to %s.\n", "Bob", "Sally");
printf("%s, s"); // Prints: "Bob said hello to Sally."
You can append a format (instead of overwriting the previous string contents) with sfmt_append
.
String Manipulation¶
There are a variety of manipulation functions available for strings. Be sure to check out the String API Reference for a full list and for more examples. Some really popular ones include sreplace
, ssplit
, and strim
.
String in C++¶
In C++ we have access to the String
class (near the bottom of cute_string.h). It wraps up the dynamic C string API into a convenience class. It will automatically call sfree
in its destructor. Here's a quick demo of some its basic features:
String s = " Well hello there! Today is <color> day, meaning everything is the color <color>. ";
s.trim().replace("<color>", "red");
printf("%s", s.c_str());
Which would output:
String Hashing¶
To get a hash of a string call shash
.
Be sure to check out this section on String Interning, which covers the String Intern API. You may use this to construct immutable strings that work super efficiently for comparisons and hash tables.
UTF8¶
It's highly recommended to store strings for your game in text files and load them up from disk. This makes it easy for a localizer to make different versions of text in different langauges without editing anything other than simple text files. The format of your strings should be in the UTF8 format, which is 100% backwards compatible with typical C-strings you're already used to.
The UTF8 format encodes a large number of characters by making certain characters take up more than a single byte. To encode or decode UTF8 characters you may call sappend_UTF8
or cf_decode_UTF8
.
In C++ we have access to the UTF8
helper class. Simply load it up with a string and call .next()
to get each decoded character with .codepoint
.
UTF8 utf8 = UTF8(my_string_in_utf8_format);
while (utf8.next()) {
DoSomethingWithCodepoint(utf8.codepoint);
}
Paths¶
The path API in CF is a set of helper functions to deal with paths as a string. It auto-magically inserts "/" between folder names as appropriate, and can pop parts of the path off the end. It's great for easily opening up and traversing directories.
Paths in C++¶
It's recommended to use the C++ wrapper for paths in CF (located at the bottom of cute_file_system.h), along with the directory wrapper.
Here's an example of creating a Cute::Path
.
There are a variety of helpful member functions on the path helper, such as checking if a path is a folder or file:
Path path = "/content/my_file.txt";
if (path.is_directory()) {
// ...
} else if (path.is_file()) {
// ...
}
It's easy to pop files or directories off the end of the path:
Path path = "/content/my_file.txt";
path.pop(1); // Path is now "/content"."
path += "other_file.txt"; // Path is now "/content/other_file.txt".
// Notice how "/" was auto-magically inserted.
You may also check if a path is a file or directory without creating a Path
instance using some static functions:
// Check if path is a directory.
if (Path::is_directory("/content/areas")) {
// ...
}
// Check if path is a file.
if (Path::is_file("/content/areas/area1.txt")) {
// ...
}
Similarly a Directory
helper class exists to easily enumerate files in a directory.