I have a library which has a function like this:
int get_user_name(const char **buffer);
in swift, should call like this:
var name:CMutablePointer<CString> = nil
get_user_name(name)
I want make use this function more comfortable so I wrapped this up:
func get_username() -> String {
var name:CMutablePointer<CString> = nil
get_user_name(name)
// how to convert name to String
}
I question is how to convert name to String
It goes something like:
var stringValue :CString = ""
name.withUnsafePointer {p in
stringValue = p.memory
}
return NSString(CString: stringValue)
You can do:
return NSString(UTF8String: name[0])
Related
Is there any way to tell Swift to check if a string ends with a symbol.
for example how can I write the code below in swift?
var string = "myString*"
if string ends with "*" {
.... do something
}
You can use the hasSuffix function.
let string = "Hello world!"
if string.hasSuffix("!") {
// do something
}
String has a method hasSuffix()
var string = "myString*"
if string.hasSuffix("*") {
.... do something
}
let str = "tHIS is A test"
let swapped_case = "This IS a TEST"
Swift noob here, how to do the second statement programatically?
This function works with all upper/lowercase characters
defined in Unicode, even those from "foreign" languages such as Ä or ć:
func swapCases(_ str : String) -> String {
var result = ""
for c in str.characters { // Swift 1: for c in str {
let s = String(c)
let lo = s.lowercased() //Swift 1 & 2: s.lowercaseString
let up = s.uppercased() //Swift 1 & 2: s.uppercaseString
result += (s == lo) ? up : lo
}
return result
}
Example:
let str = "tHIS is a test ÄöÜ ĂćŒ Α" // The last character is a capital Greek Alpha
let swapped_case = swapCases(str)
print(swapped_case)
// This IS A TEST äÖü ăĆœ α
Use switch statement in-range checks to determine letter case, and use NSString-bridged methods to convert accordingly.
let str = "tHIS is A test"
let swapped_case = "This IS a TEST"
func swapCase(string: String) -> String {
var swappedCaseString: String = ""
for character in string {
switch character {
case "a"..."z":
let uppercaseCharacter = (String(character) as NSString).uppercaseString
swappedCaseString += uppercaseCharacter
case "A"..."Z":
let lowercaseCharacter = (String(character) as NSString).lowercaseString
swappedCaseString += lowercaseCharacter
default:
swappedCaseString += String(character)
}
}
return swappedCaseString
}
swapCase(str)
I'm a bit too late but this works too :-)
let str = "tHIS is A test"
var res = ""
for c in str {
if contains("ABCDEFGHIJKLMNOPQRSTUVWXYZ", c) {
res += "\(c)".lowercaseString
} else {
res += "\(c)".uppercaseString
}
}
res
In Swift 5 I achieved it by creating a function which iterates through each character of the string, and using string methods to change each character I appended each character back into a new variable:
func reverseCase(string: String) -> String {
var newCase = ""
for char in string {
if char.isLowercase {
newCase.append(char.uppercased())
}
else if char.isUppercase {
newCase.append(char.lowercased())
}
else {
newCase.append(char)
}
}
return newCase
}
Then just pass your string through to the function when you call it in a print statement:
print(reverseCase(string: str))
You already have plenty of good succinct answers but here’s an over-elaborate one for fun.
Really this is a job for map – iterate over a collection (in this case String) and do a thing to each element (here, each Character). Except map takes any collection, but only gives you back an array, which you’d have to then turn into a String again.
But here’s a version of map that, given an extensible collection, gives you back that same kind of extensible collection.
(It does have the limitation of needing both collections to contain the same type, but that’s fine for strings. You could make it return a different type, but then you’d have to tell it which type you wanted i.e. map(s, transform) as String which would be annoying)
func map<C: ExtensibleCollectionType>(source: C, transform: (C.Generator.Element) -> C.Generator.Element) -> C {
var result = C()
for elem in source {
result.append(transform(elem))
}
return result
}
Then to write the transform function, first here’s an extension to character similar to the other answers. It does seem quite unsatisfying that you have to convert to a string just to uppercase a character, is there really no good (international characterset-friendly) way to do this?
extension Character {
var uppercaseCharacter: Character {
let s = String(self).uppercaseString
return s[s.startIndex]
}
var lowercaseCharacter: Character {
let s = String(self).lowercaseString
return s[s.startIndex]
}
}
And the function to flip the case. What I wonder is whether this pattern matching is international-friendly. It seems to be – "A"..."Z" ~= "Ä" returns true.
func flipCase(c: Character) -> Character {
switch c {
case "A"..."Z":
return c.lowercaseCharacter
case "a"..."z":
return c.uppercaseCharacter
default:
return c
}
}
Finally:
let s = map("Hello", flipCase)
// s is a String = "hELLO"
I hope this helps. inputString and resultString are the input and output respectively.
let inputString = "Example"
let outputString = inputString.characters.map { (character) -> Character in
let string = String(character)
let lower = string.lowercased()
let upper = string.uppercased()
return (string == lower) ? Character(upper) : Character(lower)
}
let resultString = String(outputString)
Is it possible to get the string value from a pointer to a string?
I am using the goopt package to handle flag parsing and the package returns *string only. I want to use these values to call a function in a map.
Example
var strPointer = new(string)
*strPointer = "string"
functions := map[string]func() {
"string": func(){
fmt.Println("works")
},
}
//Do something to get the string value
functions[strPointerValue]()
returns
./prog.go:17:14: cannot use strPointer (type *string)
as type string in map index
Dereference the pointer:
strPointerValue := *strPointer
A simple function that first checks if the string pointer is nil would prevent runtime errors:
func DerefString(s *string) string {
if s != nil {
return *s
}
return ""
}
Generic https://stackoverflow.com/a/62790458/1079543 :
func SafeDeref[T any](p *T) T {
if p == nil {
var v T
return v
}
return *p
}
In AS2 I could do the following:
String.prototype.startsWith = function(s){
return this.indexOf(s) == 1
}
thus, startsWith is available on every String object
var s = "some string to test with";
s.startsWith("some") // returns true
and did it with great repository of cool tools:
var s = "some #VAR string";
s.startsWith("some");//returns true
s.endsWith("ing");//returns true
s.contains("#");//returns true
s.dataBind({VAR: "awsome"})// returns 'some awsome string'
s = "b";
s.isAnyOf("a","b","c"); //true, because "b" is one of the options
s.isInArr(["a","b","c"]); //true, because "b" is in the passed array
var o = { foo: function(i) { return "wind " + i } }
s = "foo";
f.call(o,3) //returns "wind 3" because method foo is ivoked on o with 3
f.apply(o,[3]) //returns "wind 3" because method foo is ivoked on o with 3
var a1 = [], a2 = []
s.push(a1,a2) // pushes s into a1 and a2
And so on, and so forth with many cool things that makes coding much more fun (and blazing fast when smartly used)
It's not just about String, I have such utils for Number, Date, Boolean, and so on.
Here's what I tried:
[Test]
public function test_stringPrototype()
{
String.prototype.startsWith = function(s):Boolean
{
return return this.indexOf(s) == 1;
}
assertTrue( !!String.prototype.startsWith ) //and so far - so good ! this line passes
var s:String = "some str";
assertTrue(!!o.startsWith ) //and this won't even compile... :(
}
And this won't even compile, not to mention pass or fail the test...
error: Access of possibly undefined property startsWith through a reference with static type String.
Whats the way to do it in AS3?
you could always have the utility class that will collect all those methods and work on the string, e.g.
package utils
{
public class StringUtils
{
public static function startsWith(input:String, test:String):Boolean
{
return input.indexOf(test) == 0;
}
}
}
usage:
trace(StringUtils.startWith("My string", "My"));
or as a "global" function:
package utils
{
public function startsWith(input:String, test:String):Boolean
{
return input.indexOf(test) == 0;
}
}
usage:
trace(startWith("My string", "My"));
best regards
Yes of course, use string representation of a variable name: "startsWith"; Example down
String.prototype.traceME = function():void
{
trace(this);
}
var s:String = "some str";
s["traceME"]();
else method:
var s:Object = new String("some str");
s.traceME();
It seems AS3 has a toString() for the Number class. Is there an equivalent in Haxe? The only solution I could come up with for converting an Int to a String is a function like:
public function IntToString(i:Int):String {
var strbuf:StringBuf = new StringBuf();
strbuf.add(i);
return strbuf.toString();
}
Is there a better method that I'm overlooking?
You don't usually need to manually convert an int to a string because the conversion is automatic.
var i = 1;
var s = "" + i; // s is now "1"
The "formal" way to convert any value to a string is to use Std.string():
var s = Std.string(i);
You could also use string interpolation:
var s = '$i';
The function your wrote is fine but definitely overkilling.