How to parse Int from String.charAt() - string

I need to parse Integer from first String position.
Something like this:
String s = "1abc";
int x = s.charAt(0);
This doesn't work (obviously) but hopefully you got the idea.
I also can't use anything like this:
int x = s.substring(0, 1);
Since that would return second character ('a') in this case.

For java you could do
int x = Integer.parseInt(s.substring(0,1));
Check if it works

Related

How to get the 2nd and 3rd character of a String as Integer - C89

So if I have a String
char string[4];
string = "A10";
How Can I get 10 as an Integer.
I tried getting 10 by itself using this but it didn't work.
char string[4];
char string2[2];
string = "A10";
string2[0] = string[1];
string2[1] = string[2];
I don't need to worry about the A, I know how to get that, I need to be able to get the 10 as an integer.
In java you can use the following code to convert string to integer,
int i=Integer.parseInt(s2);
for more information view this website,
https://www.javatpoint.com/java-string-to-int

D: how to remove last char in string?

I need to remove last char in string in my case it's comma (","):
foreach(line; fcontent.splitLines)
{
string row = line.split.map!(a=>format("'%s', ", a)).join;
writeln(row.chop.chop);
}
I have found only one way - to call chop two times. First remove \r\n and second remove last char.
Is there any better ways?
import std.array;
if (!row.empty)
row.popBack();
As it usually happens with string processing, it depends on how much Unicode do you care about.
If you only work with ASCII it is very simple:
import std.encoding;
// no "nice" ASCII literals, D really encourages Unicode
auto str1 = cast(AsciiString) "abcde";
str1 = str1[0 .. $-1]; // get slice of everything but last byte
auto str2 = cast(AsciiString) "abcde\n\r";
str2 = str2[0 .. $-3]; // same principle
In "last char" actually means unicode code point (http://unicode.org/glossary/#code_point) it gets a bit more complicated. Easy way is to just rely on D automatic decoding and algorithms:
import std.range, std.stdio;
auto range = "кириллица".retro.drop(1).retro();
writeln(range);
Here retro (http://dlang.org/phobos/std_range.html#.retro) is a lazy reverse iteration function. It takes any range (unicode string is a valid range) and returns wrapper that is capable of iterating it backwards.
drop (http://dlang.org/phobos/std_range.html#.drop) simply pops a single range element and ignores it. Calling retro again will reverse the iteration order back to normal, but now with the last element dropped.
Reason why it is different from ASCII version is because of nature of Unicode (specifically UTF-8 which D defaults to) - it does not allow random access to any code point. You actually need to decode them all one by one to get to any desired index. Fortunately, D takes care of all decoding for you hiding it behind convenient range interface.
For those who want even more Unicode correctness, it should be possible to operate on graphemes (http://unicode.org/glossary/#grapheme):
import std.range, std.uni, std.stdio;
auto range = "abcde".byGrapheme.retro.drop(1).retro();
writeln(range);
Sadly, looks like this specific pattern is not curently supported because of bug in Phobos. I have created an issue about it : https://issues.dlang.org/show_bug.cgi?id=14394
NOTE: Updated my answer to be a bit cleaner and removed the lambda function in 'map!' as it was a little ugly.
import std.algorithm, std.stdio;
import std.string;
void main(){
string fcontent = "I am a test\nFile\nwith some,\nCommas here and\nthere,\n";
auto data = fcontent
.splitLines
.map!(a => a.replaceLast(","))
.join("\n");
writefln("%s", data);
}
auto replaceLast(string line, string toReplace){
auto o = line.lastIndexOf(toReplace);
return o >= 0 ? line[0..o] : line;
}
module main;
import std.stdio : writeln;
import std.string : lineSplitter, join;
import std.algorithm : map, splitter, each;
enum fcontent = "some text\r\nnext line\r\n";
void main()
{
fcontent.lineSplitter.map!(a=>a.splitter(' ')
.map!(b=>"'" ~ b ~ "'")
.join(", "))
.each!writeln;
}
Take a look, I use this extension method to replace any last character or sub-string, for example:
string testStr = "Happy holiday!";<br>
Console.Write(testStr.ReplaceVeryLast("holiday!", "Easter!"));
public static class StringExtensions
{
public static string ReplaceVeryLast(this string sStr, string sSearch, string sReplace = "")
{
int pos = 0;
sStr = sStr.Trim();
do
{
pos = sStr.LastIndexOf(sSearch, StringComparison.CurrentCultureIgnoreCase);
if (pos >= 0 && pos + sSearch.Length == sStr.Length)
sStr = sStr.Substring(0, pos) + sReplace;
} while (pos == (sStr.Length - sSearch.Length + 1));
return sStr;
}
}

Error in using indexOf not finding char in Arduino String

I have some code that I have no clue why it isn't working.
The code takes a serial input in the form of "xxx,yyy,zzz", where digits can range from 1 to 3 in each number. Because of an odd quirk in an app, it needs to be read as a char, then converted to a string to be handled. The intention is to split into 3 ints, red green and blue, from "RRR,GGG,BBB".
Now this works fine when I manually define String str (see commented code), but when I go and enter it from the serial console, it doesn't want to work. It seems to be coming from the indexOf(',') part, as while using Serial.print(c1);, I found that when I manually entered a string, it returned an index of the comma, but when I used the serial console, it returned -1 (not found).
And yes, the entered string into the console is in the correct format of "RRR,GGG,BBB", I've confirmed that by printing both phone and str independently.
while (Serial.available() > 0) {
char phone = Serial.read();
String str = String(phone);
//String str = "87,189,183";
int ln = str.length()-1;
int c1 = str.indexOf(','); //first place to cut string
int c2 = str.indexOf(',',c1+1); //second place
red = str.substring(0,c1).toInt();
green = str.substring(c1,c2).toInt();
blue = str.substring(c2,ln).toInt();
Serial.print(red);
Edit: With the Arduino String class, creating a string from a char is returning more than just one character, eleven in fact.
This:
char phone = Serial.read();
String str = String(phone);
will never create a string in str that has more than 1 character, since that's what you say you want.
This is the code for the Arduino's String(char) constructor:
String::String(char c)
{
init();
char buf[2];
buf[0] = c;
buf[1] = 0;
*this = buf;
}
So clearly your code will create a 1-character long string.
Also, beware of using indexes computed on the full string, on substrings later.
I'm try to guess that you are using these serial API http://playground.arduino.cc/Interfacing/CPPWindows.
while (Serial.available() > 0) {
char buf[12];
int len = Serial.ReadData(buf,11);
String str = String(buf);
//String str = "87,189,183";
int ln = str.length()-1;
int c1 = str.indexOf(','); //first place to cut string
int c2 = str.indexOf(',',c1+1); //second place
red = str.substring(0,c1).toInt();
green = str.substring(c1,c2).toInt();
blue = str.substring(c2,ln).toInt();
Serial.print(red);
If you are using other API like http://arduino.cc/en/Serial/Read you should follow these API where Serial is a Stream and read() return just the first available char.
Code was fixed by using a different function.
while (Serial.available() > 0) {
char phone = Serial.read();
str += phone;
//String str = "87,189,183";
int ln = str.length()-1;
int c1 = str.indexOf(','); //first place to cut string
int c2 = str.indexOf(',',c1+1); //second place
red = str.substring(0,c1).toInt();
green = str.substring(c1,c2).toInt();
blue = str.substring(c2,ln).toInt();
Serial.print(red);
I'm not sure why this works, and why before I was getting a string with more than one character. But it works!

Removing from a hashmap

Ok, so I have this easy bit of code, but I can't figure out why it doesn't work ...
int redscre = teamScore.get(TeamType.RED);
int redscore = redscre--;
teamScore.put(TeamType.RED, redscore);
It's the post-decrement operator that's tripping you up:
int redscore = redscre--;
This is the sequence of events that occur:
The value of redscre gets assigned to redscore
redscre is decremented, redscore is unchanged
Then you put the unchanged value of redscore back into the hashmap.
Change to the pre-decrement operator to make it work:
int redscre = teamScore.get(TeamType.RED);
teamScore.put(TeamType.RED, --redscre);
Or if you want to do things more explicitly:
int redscre = teamScore.get(TeamType.RED);
int redscore = redscre - 1;
teamScore.put(TeamType.RED, redscore);
This wikipedia article provides a good explanation about the differences between pre- and post-increment/decrement operators.
The problem is you are using the post decrement operator.
Redscrore is set to the value of redscr and then redsrc is decremented
Try this:
int redscre = teamScore.get(TeamType.RED);
int redscore = redscre - 1; // This statement returns the proper value.
teamScore.put(TeamType.RED, redscore);
Another solution would be to use the pre-decrements operator (redscroe = --redscr), but seeing as redscr is just a temporary, there really isn't a good reason to do this.

d programming, parse or convert string to double

as easy as it is in other languages, i can't seem to find an option in the d programming language where i can convert a string (ex: "234.32") into a double/float/real.
using atof from the std.c.stdio library only works when i use a constant string. (ex: atof("234.32") works but atof(tokens[i]); where tokens is an dynamic array with strings doesn't work).
how to convert or parse a string into a real/double/float in the d-programming language?
Easy.
import std.conv;
import std.stdio;
void main() {
float x = to!float("234.32");
double y = to!double("234.32");
writefln("And the float is: %f\nHey, we also got a double: %f", x, y);
}
std.conv is the swiss army knife of conversion in D. It's really impressive!
To convert from most any type to most any other type, use std.conv.to. e.g.
auto d = to!double("234.32");
or
auto str = to!string(234.32);
On the other hand, if you're looking to parse several whitespace-separated values from a string (removing the values from the string as you go), then use std.conv.parse. e.g.
auto str = "123 456.7 false";
auto i = parse!int(str);
str = str.stripLeft();
auto d = parse!double(str);
str = str.stripLeft();
auto b = parse!bool(str);
assert(i == 123);
assert(d == 456.7);
assert(b == false);

Resources