Can someone help me to understand why if my val value is a "0" Integer.parseInt(val) returns me NumberFormatException and if i write Integer.parseInt("0") it works correctly...
There's a way easier to work directly with the int value read from Serial?
void draw(){
i=0;
byte[] str = new byte[5];
if ( myPort.available() > 0)
{
myPort.readBytesUntil(10, inBuffer);
if(inBuffer==null){
//...
}
else
{
while(inBuffer[i]!=13){
str[i]=inBuffer[i];
println((int)str[i]);
i++;
}
String val = new String(str);
i = Integer.parseInt(val);
println(i);
}
}
}
In Processing port.readBytesUntil(ch, buffer) reads all characters from port until encounter character equal to ch.
In Windows line separator is composed from 2 characters (0d,0a) or (13,10).
So if you write to serial "23", next newline, next "45", etc., the buffer will look like this:
char[] buffer : '2', '3', '0x0d', '0x0a', '4', '5', '0x0d', '0x0a', ...
So when you readBytesUntil(10, ...) it read 3 characters: '2', '3', '0x0d'.
Consider such example:
char[] c = {'2', '3', 13};
String str = new String(c);
System.out.println(str); // you will see "23"
System.out.println(str.length()); // lenght will be 3
System.out.println(Integer.parseInt(str.trim())); // will be OK
System.out.println(Integer.parseInt(str)); // will throw NumberFormatException
So try to convert your buffer to String and trim() this string.
== EDIT ==
Processing gives you some convenience methods such as:
String str = port.readStringUntil(10);
str = str.trim();
Can you provide an MCVE that demonstrates the problem? Use hardcoded values and keep it as simple as possible, like this:
void setup(){
String val = "0";
int i = Integer.parseInt(val);
println(i);
}
Print out the value of val before you try parsing it. I would bet it's not the value you think it is.
Related
I'm getting an error in this code:
void main() {
List<String> wave(String str) {
List<String> results = [];
String newStr;
int i = 0;
for (String ltr in str.split('')) {
newStr = str;
if (ltr != ' ') {
newStr[i] = ltr.toUpperCase();
results.add(newStr);
}
i++;
}
return results;
}
print(wave(' gap '));
}
the error is at the line:
newStr[i] = ltr.toUpperCase;
Despite when I try print(newStr[i]); I don't get an error and the code is executed correctly!
In Dart String operation, operator[] returns a string. Which means, array[index] is used for getting the string in the index position. That is why you're getting that error, because you can't set at specific index using this operator[] in dart. See the documentation for details.
To replace at the specific index in dart, you can use replaceFirst(Pattern from, String to, [int startIndex = 0]) as the other answer mentioned. Or, you can use substring(int start, [int? end]) as follows:
if (ltr != ' ' && i < newStr.length) {
newStr = newStr.substring(0, i) + ltr.toUpperCase() + newStr.substring(i+1);
results.add(newStr);
}
To make the code bug free, I've added the checking of the value of i in it. You should add the checking to avoid out of bound access.
try to replace
newStr[i] = ltr.toUpperCase();
to
newStr = newStr.replaceFirst(ltr,ltr.toUpperCase(),i);
So the result will be [ Gap , gAp , gaP ]
Honestly, I don't know how char is defined in Dart, but I think accessing index of String is kind of getter, thus cannot be set to a new value.
I want to put each word in a string into a separate string. So if my string has a list of words like, "John, Mary, Barbara" and the words are separate by a carriage return (not a comma as shown in the example), how do I put John into one string, Mary into another string and Barbara into a third string. The strings are not created so I will have to create them on the fly and that is ok. This is what I have tried:
for (n; n<100; n++){
s1 = s[n:n]
if(s1 == "\n") {
break
}
}
Since I want this separation to occur for every object (a specific column in a module) I will have to put whatever the correct code is into a loop like "for o in m do{ }.
Thank you for helping me.
Maybe these functions would help. However, you would have to get familiar with the Skip type (the DXL manual helps with that).
stringSplit() divides str into substrings based on a delimiter, returning an array (Skip type) of these substrings. If pattern is a String, then its contents are used as the delimiter when splitting str. If pattern is empty or null, the value of a single space is used. If pattern is a single space, str is split on whitespace, with leading whitespace and runs of contiguous whitespace characters ignored.
Skip stringSplit(string str, string pattern) {
if (null str) return null
if (null(pattern) || 0 == length(pattern))
pattern = " ";
Skip result = create;
int i = 0; // index for searching in str
int j = 0; // index counter for result array
bool found = true;
while (found) {
// find pattern
int pos = 0;
int len = 0;
found = findPlainText(str[i:], pattern, pos, len, true);
if (found) {
// insert into result
put(result, j++, str[i:i+pos-1]);
i += pos + len;
}
}
// append the rest after last found pattern
put(result, j, str[i:]);
return result;
}
You might prefer to remove the commas first since the last word is not followed by a comma.
stringWipe() returns a copy of str with all occurrences of characters in chars eliminated:
string stringWipe(string str, string chars) {
if (null str) return str
int lenStr = length str
if (lenStr == 0) return str
int lenChars = length(chars);
if (lenChars == 0) return str
Buffer buf = create
int i
for (i=0; i<lenStr; i++) {
char c = str[i]
bool skip = false
int j
for (j=0; j<lenChars; j++) {
if (c == chars[j]) {
skip = true
break
}
}
if (skip)
continue
buf += c
}
string result = stringOf(buf);
delete buf
return result
}
Is there a way to split a string by some symbol but only at first occurrence?
Example: date: '2019:04:01' should be split into date and '2019:04:01'
It could also look like this date:'2019:04:01' or this date : '2019:04:01' and should still be split into date and '2019:04:01'
string.split(':');
I tried using the split() method. But it doesn't have a limit attribute or something like that.
You were never going to be able to do all of that, including trimming whitespace, with the split command. You will have to do it yourself. Here's one way:
String s = "date : '2019:04:01'";
int idx = s.indexOf(":");
List parts = [s.substring(0,idx).trim(), s.substring(idx+1).trim()];
You can split the string, skip the first item of the list created and re-join them to a string.
In your case it would be something like:
var str = "date: '2019:04:01'";
var parts = str.split(':');
var prefix = parts[0].trim(); // prefix: "date"
var date = parts.sublist(1).join(':').trim(); // date: "'2019:04:01'"
The trim methods remove any unneccessary whitespaces around the first colon.
Just use the split method on the string. It accepts a delimiter/separator/pattern to split the text by. It returns a list of values separated by the provided delimiter/separator/pattern.
Usage:
const str = 'date: 2019:04:01';
final values = string.split(': '); // Notice the whitespace after colon
Output:
Inspired by python, I've wrote this utility function to support string split with an optionally maximum number of splits. Usage:
split("a=b=c", "="); // ["a", "b", "c"]
split("a=b=c", "=", max: 1); // ["a", "b=c"]
split("",""); // [""] (edge case where separator is empty)
split("a=", "="); // ["a", ""]
split("=", "="); // ["", ""]
split("date: '2019:04:01'", ":", max: 1) // ["date", " '2019:04:01'"] (as asked in question)
Define this function in your code:
List<String> split(String string, String separator, {int max = 0}) {
var result = List<String>();
if (separator.isEmpty) {
result.add(string);
return result;
}
while (true) {
var index = string.indexOf(separator, 0);
if (index == -1 || (max > 0 && result.length >= max)) {
result.add(string);
break;
}
result.add(string.substring(0, index));
string = string.substring(index + separator.length);
}
return result;
}
Online demo: https://dartpad.dev/e9a5a8a5ff803092c76a26d6721bfaf4
I found that very simple by removing the first item and "join" the rest of the List
String date = "date:'2019:04:01'";
List<String> dateParts = date.split(":");
List<String> wantedParts = [dateParts.removeAt(0),dateParts.join(":")];
Use RegExp
string.split(RegExp(r":\s*(?=')"));
Note the use of a raw string (a string prefixed with r)
\s* matches zero or more whitespace character
(?=') matches ' without including itself
You can use extensions and use this one for separating text for the RichText/TextSpan use cases:
extension StringExtension on String {
List<String> controlledSplit(
String separator, {
int max = 1,
bool includeSeparator = false,
}) {
String string = this;
List<String> result = [];
if (separator.isEmpty) {
result.add(string);
return result;
}
while (true) {
var index = string.indexOf(separator, 0);
print(index);
if (index == -1 || (max > 0 && result.length >= max)) {
result.add(string);
break;
}
result.add(string.substring(0, index));
if (includeSeparator) {
result.add(separator);
}
string = string.substring(index + separator.length);
}
return result;
}
}
Then you can just reference this as a method for any string through that extension:
void main() {
String mainString = 'Here was john and john was here';
print(mainString.controlledSplit('john', max:1, includeSeparator:true));
}
Just convert list to string and search
productModel.tagsList.toString().contains(filterText.toLowerCase())
How can I format an integer such as "20190331" to output as "2019-03-31" without firstly converting it to a date and without splitting it using substring. The date is stored as an integer in SQLite (SQFlite). I would like to do it in 1 line such as (pseudo code) Note: integer :
(pseudo) String sDate = fmt("####'-'##'-'##", map["DueDate"]);
I know that I could do it such as :
String sDate = map["DueDate"].toString();
sDate = sDate.substring(0,4)+'-'+sDate.substring(4,6)+'-'+sDate.substring(6,8);
That however is two lines of code, and Visual Studio Code turns it into 8 lines when formatted and I like to keep my code compact.
Write a function called fmt and call it as in your pseudo code.
String fmt(String f, int i) {
StringBuffer sb = StringBuffer();
RuneIterator format = RuneIterator(f);
RuneIterator input = RuneIterator(i.toString());
while (format.moveNext()) {
var currentAsString = format.currentAsString;
if (currentAsString == '#') {
input.moveNext();
sb.write(input.currentAsString);
} else {
sb.write(currentAsString);
}
}
return sb.toString();
}
one line:
print(fmt('####-##-##', 20190331));
I would like to edit the elements of string array with DXL script which is used in for loop. The problem will be described in the following:
I would like to insert space in front of every upper case letter expect the first one and it would be applied for all lines in string array.
Example:
There is a string array:
AbcDefGhi
GhiDefAbc
DefGhiAbc
etc.
and finally I would like to see the result as:
Abc Def Ghi
Ghi Def Abc
Def Ghi Abc
etc.
Thanks in advance!
Derived straightly from the DXL manual..
Regexp upperChar = regexp2 "[A-Z]"
string s = "yoHelloUrban"
string sNew = ""
while (upperChar s) {
sNew = sNew s[ 0 : (start 0) - 1] " " s [match 0]
s = s[end 0 + 1:]
}
sNew = sNew s
print sNew
You might have to tweak around the fact that you do not want EVERY capital letter to be replaced with , only those that are not at the beginning of your string.
Here's a solution written as a function that you can just drop into your code. It processes an input string character by character. Always outputs the first character as-is, then inserts a space before any subsequent upper-case character.
For efficiency, if processing a large number of strings, or very large strings (or both!), the function could be modified to append to a buffer instead of a string, before finally returning a string.
string spaceOut(string sInput)
{
const int intA = 65 // DECIMAL 65 = ASCII 'A'
const int intZ = 90 // DECIMAL 90 = ASCII 'Z'
int intStrLength = length(sInput)
int iCharCounter = 0
string sReturn = ""
sReturn = sReturn sInput[0] ""
for (iCharCounter = 1; iCharCounter < intStrLength; iCharCounter++)
{
if ((intOf(sInput[iCharCounter]) >= intA)&&(intOf(sInput[iCharCounter]) <= intZ))
{
sReturn = sReturn " " sInput[iCharCounter] ""
}
else
{
sReturn = sReturn sInput[iCharCounter] ""
}
}
return(sReturn)
}
print(spaceOut("AbcDefGHi"))