(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 字符串。 似乎 蓝牙在整个字符串的每个字符之间发送了一个空字符。我不明白为什么会发生这种情况,它实际上在读取传入的字符串时消耗了一些时间。如果有人有其他想法,我真的很想得到另一个答案...