Alert deprecated: Stdlib.String.set - ocaml

The following code returns an error and says that the syntax is deprecated. What is the correct way to change a character in a string?
let hello = "Hello!" ;;
hello.[1] <- 'a' ;;
Alert deprecated: Stdlib.String.set
Use Bytes.set instead.
Error: This expression has type string but an expression was expected of type
bytes

Strings are immutable (or at least soon they will be), so you can't change their contents. You can, of course, create a copy of a string with the one character different, e.g.,
let with_nth_char m c =
String.mapi (fun i b -> if i = m then c else b)
and
# with_nth_char 1 'E' "hello";;
- : string = "hEllo"
But if you need to change characters in an array then you shouldn't use the string data type but instead rely on bytes which is a type for mutable strings. You can use Bytes.of_strings and Bytes.to_string to translate strings to bytes and vice verse.

Related

Ocaml Conversion String to int to char

I need to implement this function somewhere
String.get: string -> int -> char
I have tried this one but it does not seem to work
let String.get = fun x -> char_of_int(int_of_string x) ;;
The error I get is:
let String.get = fun x -> char_of_int(int_of_string x) ;;
^^^
Error: Syntax error
String.get is a syntax to denote the function get in module String. The syntax can not be used to (re)define a function as you wrote.
The function is documented here:
val get : string -> int -> char
String.get s n returns the character at index n in string s. You can also write s.[n] instead of String.get s n.
Raise Invalid_argument if n not a valid index in s.
What you are trying to implement is different, you are trying to read, from the string, an integer, and then convert it to a digit char (?)
Depending on what your actual requirements are, you might be asked to reimplement String.get on your own, so for example you would pick a different name in your current module (for now, this is sufficient, you don't need to bother about modules):
let char_at s n = ...
Or maybe you do actually need to convert from an integer. Please clarify your question.

How do you call a batch file with an argument that has quotes, using system()

For example, in the command line this works (the 1st argument has quotes but the 2nd argument doesn't):
"test.bat" "a" b
i.e it know that "a" is the 1st argument and b is the second
but using system() it doesn't work:
system("test.bat" "a" b)
this also doesn't work:
system("test.bat" \"a\" b)
This is gonna be simplest if we use a raw string literal. A raw string literal is a way of writing a string in c++ where nothing gets escaped. Let's look at an example:
char const* myCommand = R"(test.bat "a" b)";
The R at the beginning indicates that it's a raw string literal, and if you call system(myCommand), it will be exactly equivalent to typing
$ test.bat "a" b
into the command line. Now, suppose you want to escape the quotes on the command line:
$ test.bat \"a\" b
With a raw string literal, this is simple:
char const* myCommand = R"(test.bat \"a\" b)";
system(myCommand);
Or, alternatively:
system(R"(test.bat \"a\" b)");
Hope this helps!
A bit more info on raw string literals: Raw string literals are a great feature, and they basically allow you to copy+paste any text directly into your program. They begin with R, followed by a quote and a parenthesis. Only the stuff inside the parenthesis gets included. Examples:
using std::string;
string a = R"(Hello)"; // a == "Hello"
Begin and end with "raw":
string b = R"raw(Hello)raw"; // b == "Hello"
Begin and end with "foo"
string c = R"foo(Hello)foo"; // c == "Hello"
Begin and end with "x"
string d = R"x(Hello)x"; // d == "Hello"
The important thing is that we begin and end the literal with the same string of letters (called the delimiter), followed by the parenthesis. This ensures we never have a reason to escape something inside the raw string literal, because we can always change the delimiter so that it's not something found inside the string.
I got it to work now:
system(R"(C:\"to erase\test.bat" "a")");
I found the answer: system("test.bat" ""a"" b);
or more precisely: system("\"test.bat\" ""a"" b");
So the answer is to escape the quotes with a double quote

Creates a string containing the given character issue

In the Apple Documentation :
init(_: Character)
Creates a string containing the given character.
c: The character to convert to a string.
Declaration
init(_ c: Character)
I try to create a string with a character using string init but I fail.I don't understand the declaration above.I want to create a string including "k".
Here is example:
String(_ c: "k") // fails
String("k" c: Character) // fails
What is the correct way acoording to declaration above.I don't understand what _: means in the declaration.
Can someone explain what the declaration means in human language ?
init(_: Character)
^
means the parameter doesn't have an external name. So when you call that initializer you simply put the value, without a label.
Like this
let char: Character = "A"
let word = String(char)

How to concatenate string in ROOT,c++?

I want to concatenate two string and I did in my program like String Filename = name+ "" + extension where extension is an integer value that I read just above this line and name is the path that is already defined.
But in ROOT I am getting error like Error: + illegal operator for pointer 1
What went wrong here? Is there any other method?
If extension is an integer, then convert it to a string first.
std::string Filename = name+ "" + std::to_string(extension);
+""+ does nothing, btw
The TString class in ROOT has a function called "Format" which you can use to concatenate strings the same way you format a print statement. Here is the documentation for the Format method: https://root.cern.ch/root/html/TString.html#TString:Format
and here is the documentation for how the formatting works http://www.cplusplus.com/reference/cstdio/printf/
I'm going to go ahead and assume the 'name' is a char*.
Char const* name = "john";
Char const* space = " ";
Here name and space are 2 pointers to character arrays.
When you add try to add these 2 together, the compiler tries to add the value of the 2 pointer together. This makes no sense to the compiler. You can obviously only add an offset to a pointer.
The solution to this is to make sure that one of the 2 things you are adding is a std::string and not 'c string'.

Issues with declaring and writing to arrays with Arduino and C++

I'm messing around with an Arduino board for the first time.
I have an array declared like this (I know don't judge me), it's for storing each character of the LCD as a sort of cache:
char* lcd_characters[] = {"","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""};
Then later on I'm trying to write to a specific slot of the array, like this, to save that letter to it:
new_char = String(message.charAt(i));
...blah blah blah...
lcd_characters[pos] = new_char; << error here
However it is giving me this error:
error: cannot convert 'String' to 'char*' in assignment
The funny thing is when I do this (below) it do assign the letter to it, however I have a var which is a single letter but can't assign it.
lcd_characters[pos] = "H";
Can someone help me out please. Thanks. I'm brand new to C and been ok so far.
Basically I want an array of characters and then I want to write on the array positions with a new value.
Why does it even matter what type of string I'm writing to that array position, I should be able to write a number or boolean there too and call it later. Is there something wrong with the way the array is declared initially?
Edit:
I tried...
lcd_characters[pos] = new_char.c_str();
however that's giving me the similar error:
invalid conversion from 'const char*' to 'char'
Wtf? All I want to do is say this array position equals this new value. That's it. I've done this a million times in javascript, ruby, python (even php) etc. I just want to go, this array... x[12] equals my letter in new_char !!!! Ahh.
A few remarks:
Are you using C or C++? String is a C++ class, but you are creating a an array of c strings (char *).
You are creating an array of strings (char* var[] equals to char**), but your naming suggests you want an array of characters. A c string is basically an array of characters, so stick with that (char * or char []).
I would recommend you go for only C code in this case:
char lcdChars[4] = {' ', ' ', ' ', ' '}; // init with spaces
lcdChars[2] = 'x'; // write x to position 3
Note: A string in C++ can output a C string (char *) by calling stringInstance.c_str().