(Java + Android) 解析字符串浮动奇怪的错误
(Java + Android) Parsing string to float strange error
这听起来像是一个微不足道的问题,但我真的很难弄明白。基本上我从我的 Android 发送一个字符串到我的电脑。一切连接正常,字符串传输成功。这是 Android 代码(将字符串发送到计算机):
try
{
println(scSocket + "");
if (scSocket!=null)
{
SendReceiveBytes sendReceiveBT = new SendReceiveBytes(scSocket);
String red = rotZ + " \n";
byte[] myByte = stringToBytesUTFCustom(red);
sendReceiveBT.write(myByte);
}
}
catch(Exception e)
{
println(e);
}
其中rotZ是我要发送的,是一个"float"值。我需要将“\n”放在消息的末尾,以便在 PC 上将其识别为完整消息。到目前为止,一切都很好。现在我想在我的电脑上阅读这个,这是通过以下方式实现的:
//BlueTooth
String lineRead = "";
try
{
lineRead = new String(sampleSPPServer.readFromDevice());
if(lineRead != null && !lineRead.isEmpty())
{
String lineTransf = lineRead.replace("\n", "").replace("\r", "").replace(" ", "").replace("\"", "").trim();
println("LineTransf: " + lineTransf);
rotZ += 0.01*(Float.parseFloat(lineTransf));
println("Zrotation: " + rotZ); //Never gets here, throws and error before...
}
else
rotZ += 0;
}
catch(Exception e)
{
println("Exception: " + e);
}
这给了我错误:
NumberFormatException: invalid float value: "1.1400002"
在我的代码中,您可以看到我检查了 null、empty 等。所以这不是问题所在。我已经试过了:
NumberFormat nf = NumberFormat.getInstance(Locale.US);
rotZ += 0.01*(nf.parse(lineTransf).floatValue());
得到相同的结果...在Whosebug中有一个类似的问题:
Here
还有一件奇怪的事情,如果我试试代码:
for(int i = 0; i < lineTransf.length(); i++)
println(lineTransf.substring(i,1));
我知道字符串的长度是 19,但它只打印前两个并给出消息:
Exception: java.lang.StringIndexOutOfBoundsException: String index out of range: -1
更奇怪的是,当我对控制台中出现的数字“1.1400002”执行 ctrl-c、ctrl-v 时,它只在堆栈溢出时在此处粘贴“1”。
我知道这个数字是正确的,但在某个地方转换不正确。我认为那是因为字符串作为字节发送并作为字符串读取,但我该如何解决这个问题?提前致谢!!
没什么奇怪的。这是 substring
的预期行为。它抛出一个 IndexOutOfBoundsException
,如果 startIndex
为负数,则 endIndex
大于字符串的长度,或者如果 startIndex
大于 endIndex
(这是你的案件)。对我来说,您似乎想在 index.html 处打印字符。试试
for(int i = 0; i < lineTransf.length(); i++)
println(lineTransf.charAt(i));
我找到了解决方法,但我真的非常想要一个解释(如果可能的话),因为这太丑陋了......我将代码更改为:
//BlueTooth
String lineRead = "";
try
{
lineRead = new String(sampleSPPServer.readFromDevice());
if(lineRead != null && !lineRead.isEmpty())
{
String lineTransf = lineRead.replace("\n", "").replace("\r", "").replace(" ", "").replace("\"", "").trim();
println("LineTransf: " + lineTransf + " " + lineTransf.length());
String lastTry = "";
for(int i = 0; i < lineTransf.length(); i++)
{
if(lineTransf.charAt(i) != ' ' && lineTransf.charAt(i) != '\u0000')
{
println(lineTransf.charAt(i));
lastTry += lineTransf.charAt(i);
}
}
println("LastTry: " + lastTry);
rotZ += 0.01*(Float.parseFloat(lastTry));
println("Zrotation: " + rotZ);
}
else
rotZ += 0;
//System.out.println("Line Read:" + lineRead);
}
catch(Exception e)
{
println("Exception: " + e);
}
我基本上是在创建一个名为 lastTry 的新字符串,然后检查每个蓝牙读取字符是否不为空(?) null(?)(因为我正在测试:)
if(lineTransf.charAt(i) != ' ' && lineTransf.charAt(i) != '\u0000')
如果他们通过了这个测试,我将单独 "assemble" lastTry 字符串。 似乎 蓝牙在整个字符串的每个字符之间发送了一个空字符。我不明白为什么会发生这种情况,它实际上在读取传入的字符串时消耗了一些时间。如果有人有其他想法,我真的很想得到另一个答案...
这听起来像是一个微不足道的问题,但我真的很难弄明白。基本上我从我的 Android 发送一个字符串到我的电脑。一切连接正常,字符串传输成功。这是 Android 代码(将字符串发送到计算机):
try
{
println(scSocket + "");
if (scSocket!=null)
{
SendReceiveBytes sendReceiveBT = new SendReceiveBytes(scSocket);
String red = rotZ + " \n";
byte[] myByte = stringToBytesUTFCustom(red);
sendReceiveBT.write(myByte);
}
}
catch(Exception e)
{
println(e);
}
其中rotZ是我要发送的,是一个"float"值。我需要将“\n”放在消息的末尾,以便在 PC 上将其识别为完整消息。到目前为止,一切都很好。现在我想在我的电脑上阅读这个,这是通过以下方式实现的:
//BlueTooth
String lineRead = "";
try
{
lineRead = new String(sampleSPPServer.readFromDevice());
if(lineRead != null && !lineRead.isEmpty())
{
String lineTransf = lineRead.replace("\n", "").replace("\r", "").replace(" ", "").replace("\"", "").trim();
println("LineTransf: " + lineTransf);
rotZ += 0.01*(Float.parseFloat(lineTransf));
println("Zrotation: " + rotZ); //Never gets here, throws and error before...
}
else
rotZ += 0;
}
catch(Exception e)
{
println("Exception: " + e);
}
这给了我错误:
NumberFormatException: invalid float value: "1.1400002"
在我的代码中,您可以看到我检查了 null、empty 等。所以这不是问题所在。我已经试过了:
NumberFormat nf = NumberFormat.getInstance(Locale.US);
rotZ += 0.01*(nf.parse(lineTransf).floatValue());
得到相同的结果...在Whosebug中有一个类似的问题: Here
还有一件奇怪的事情,如果我试试代码:
for(int i = 0; i < lineTransf.length(); i++)
println(lineTransf.substring(i,1));
我知道字符串的长度是 19,但它只打印前两个并给出消息:
Exception: java.lang.StringIndexOutOfBoundsException: String index out of range: -1
更奇怪的是,当我对控制台中出现的数字“1.1400002”执行 ctrl-c、ctrl-v 时,它只在堆栈溢出时在此处粘贴“1”。 我知道这个数字是正确的,但在某个地方转换不正确。我认为那是因为字符串作为字节发送并作为字符串读取,但我该如何解决这个问题?提前致谢!!
没什么奇怪的。这是 substring
的预期行为。它抛出一个 IndexOutOfBoundsException
,如果 startIndex
为负数,则 endIndex
大于字符串的长度,或者如果 startIndex
大于 endIndex
(这是你的案件)。对我来说,您似乎想在 index.html 处打印字符。试试
for(int i = 0; i < lineTransf.length(); i++)
println(lineTransf.charAt(i));
我找到了解决方法,但我真的非常想要一个解释(如果可能的话),因为这太丑陋了......我将代码更改为:
//BlueTooth
String lineRead = "";
try
{
lineRead = new String(sampleSPPServer.readFromDevice());
if(lineRead != null && !lineRead.isEmpty())
{
String lineTransf = lineRead.replace("\n", "").replace("\r", "").replace(" ", "").replace("\"", "").trim();
println("LineTransf: " + lineTransf + " " + lineTransf.length());
String lastTry = "";
for(int i = 0; i < lineTransf.length(); i++)
{
if(lineTransf.charAt(i) != ' ' && lineTransf.charAt(i) != '\u0000')
{
println(lineTransf.charAt(i));
lastTry += lineTransf.charAt(i);
}
}
println("LastTry: " + lastTry);
rotZ += 0.01*(Float.parseFloat(lastTry));
println("Zrotation: " + rotZ);
}
else
rotZ += 0;
//System.out.println("Line Read:" + lineRead);
}
catch(Exception e)
{
println("Exception: " + e);
}
我基本上是在创建一个名为 lastTry 的新字符串,然后检查每个蓝牙读取字符是否不为空(?) null(?)(因为我正在测试:)
if(lineTransf.charAt(i) != ' ' && lineTransf.charAt(i) != '\u0000')
如果他们通过了这个测试,我将单独 "assemble" lastTry 字符串。 似乎 蓝牙在整个字符串的每个字符之间发送了一个空字符。我不明白为什么会发生这种情况,它实际上在读取传入的字符串时消耗了一些时间。如果有人有其他想法,我真的很想得到另一个答案...