0

I am aware similar questions have been asked here before, but I have not found anything that works for me, so I am desperate.

I am receiving a number of values from Bluetooth, which are separated by commas, and I receive them as string. They can be both positive or negative decimal numbers. For example: 0, 1.11, 2.22, -3.33, -4.44, 55.55, 66.66, -77.77, 8.88, 0

I am however unable to extract all the numbers as they are. I have tried Regex, I have tried splitting and parsing, I have tried parsing to decimal, double, however I get unhandled exceptions for the Parse functions every single time.

Any help for a definitive solution is appreciated.

EDIT: Here's the part of the code where I'm trying to parse:

    public static void AddToGraphs(string list) {
    try
    {
        var data = list.Split(',').Select(x => double.Parse(x, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture));
        double[] dataArray = data.ToArray();
    }
    catch (Java.IO.IOException e)
    {
        Log.WriteLine(LogPriority.Error, e.Source, e.Message);
    }
}

Here's the call stack when the app crashes:

        0xFFFFFFFFFFFFFFFF in 
    System.Diagnostics.Debugger.Mono_UnhandledException_internal    C#
            0x1 in System.Diagnostics.Debugger.Mono_UnhandledException  C#
            0x26 in object.6f90deee-2618-4e76-9135-3c21efb2de46 C#


    0x96 in System.Number.ParseDouble   C#
        0x3 in double.Parse C#
        0xE in double.Parse C#
        0x8 in Namespace.<>c.<AddToGraphs>b__38_0   C#
        0x26 in System.Linq.Enumerable.SelectArrayIterator<string,double>.ToArray  C#
        0x20 in System.Linq.Enumerable.ToArray<double>  C#
        0x37 in Namespace.Page3Fragment.AddToGraphs C#
        0x5A in Namespace.Page1Fragment.MyHandler.HandleMessage C#
        0x11 in Android.OS.Handler.n_HandleMessage_Landroid_os_Message_ C#
        0x17 in object.6f90deee-2618-4e76-9135-3c21efb2de46 C#

EDIT: This is the logcat, with the 'list' variable logged, just before the app crashes:

Time    Device Name Type    PID Tag Message
07-31 00:55:30.097  Samsung SM-G610F    Info    32398   Test    0
07-31 00:55:30.157  Samsung SM-G610F    Info    32398   Test    , 1.11, 2.

EDIT: This is the the Bluetooth Service which is sending the received data to the handler:

byte[] buffer = new byte[8192];
int bytes;
while (true)
{
    bytes = ipStream.Read(buffer, 0, buffer.Length);
    try
    {
        myService.myHandler.ObtainMessage(Page1Fragment.DATA_READ, bytes, -1, buffer).SendToTarget();
    }
    catch (Java.IO.IOException e)
    {
        throw e;
    }
}

Here's the snippet of the handler where it is received and passed to the AddToGraphs function:

private class MyHandler : Handler
{
    Page1Fragment page1;
    public MyHandler(Page1Fragment _page1)
    {
        page1 = _page1;
    }
    public override void HandleMessage(Message msg) 
    {
        byte[] readBuf = (byte[])msg.Obj;
        string inData = Encoding.ASCII.GetString(readBuf, 0, msg.Arg1);
        Page3Fragment.AddToGraphs(inData);
    }
}
Sanat
  • 133
  • 1
  • 1
  • 9

2 Answers2

2

This should do the trick:

var data = "0, 1.11, 2.22, -3.33, -4.44, 55.55, 66.66, -77.77, 8.88, 0";
var arr = Array.ConvertAll(data.Split(','), 
                           x => double.Parse(x,CultureInfo.InvariantCulture));
Jonas
  • 737
  • 1
  • 8
  • 20
  • I am sending this string: "0, 1.11, 2.22, -3.33, -4.44, 55.55, 66.66, -77.77, 8.88, 0" I am sending it from Arduino over Bluetooth, reading it in a BluetoothReceiver class, which works perfectly. It sends this string as message to my handler in my activity, from where I pass it to the AddToGraphs function. – Sanat Jul 30 '17 at 19:01
  • Clearly that is not the string that is read in your system as both answers given here successfully parses that string to a list of doubles. You need to find out exactly what string you are trying to parse. Put a breakpoint in the beginning of your AddToToGraphs function and see what the actual value of the list argument is. – Jonas Jul 30 '17 at 19:09
  • You're right, it seems the entire string is not getting sent at once, I am getting it part by part from the source. First the 'list' is "0", then ", 1.11, 2" and then the app is crashing as the operation is getting performed on that. I don't know how to fix that. Is it because the Arduino Bluetooth is sending it serially? – Sanat Jul 30 '17 at 19:27
  • I do not have the knowledge to help you with this. You will have to read the documentation for the library you are using to see if there is a way to ensure you have received all data. Alternative you will need to save anything after the last delimiter and save that until you receive more data to see if you got the full number. This can be done by storing the remainder for the input in a static variable which is prepended to the next data chunk received by the system. – Jonas Jul 30 '17 at 19:40
1

You should use correct culture when parsing real numbers. See this thread

As to your task I would do this:

var numbers = "0, 1.11, 2.22, -3.33, -4.44, 55.55, 66.66, -77.77, 8.88, 0"
            .Split(new char [] { ',' }, StringSplitOptions.RemoveEmptyEntries)
            .Select(x => double.Parse(x, CultureInfo.InvariantCulture)).ToArray();

EDIT:

The thing is the message is not going to come all at once. Therefore you need to create a buffer to store data until you have the whole message.

Also if you don't know the length of the message in advance you should send it as part of the message, for instance in first 4 bytes (Int32).

Alexander Mokin
  • 2,264
  • 1
  • 9
  • 14