1

I am receiving a buffer over a udp socket connection. The code is c++. The output is like:

>>375.5,25.3

where the numbers are separated by a comma and no spaces. And every 100ms a new set of numbers a sent. so like:

>>375.5,25.3
>>435.6,0.0
>>2500.34,55.2

and so on.

I am trying to put the first number in var1 and the second number in var2 for each new set. var1 and var2 are not arrays. Imagine I just need to print something like:

>>var1=375.5
  var2=25.3
>>var1=435.6
  var2=0.0

Here is the code that I am using:

recv_len = recvfrom(s, buff, sizeof(buff), 0, (struct sockaddr *)&si_other, (socklen_t*)&slen);

        if (recv_len== -1)
        {
            printf("Receiving message failed");
            exit(0);
        }
  buff[recv_len] = '\0';


    std::vector<int> vect;

    std::stringstream ss(buff);

    int i;

    while (ss >> i)
    {
        vect.push_back(i);

        if (ss.peek() == ',' || ss.peek() == ' ')
            ss.ignore();
    }

   var1 = vect.at(0);
   var2 = vect.at(1);

   printf("Received packet from %s:%d\nData:%s\n\n",inet_ntoa(si_other.sin_addr),ntohs(si_other.sin_port),buff);

    cout<<var1<<endl;
    cout<<var2<<endl;

the output I get is an error, something about the size being 1. (sorry, I didn't save the output of this to give the exact error output. I will edit tomorrow.) when I comment out the "var2 = vect.at(1)" the output is:

>>Received packet from 127.0.0.1:31029
  Data: 375.5,25.3
  375.5
  0

so it shows that there is both numbers that I need, but it won't allow me to separate them. I got the separate by comma from this: Parsing a comma-delimited std::string but is giving me an error.

I just need to separate the buffer each time it comes in like:

>>375.5,25.3

comes in, put var1 = 375.5 and var2 = 25.3, then

>>435.6,0.0 

comes in, put var1 = 435.6 and var2 = 0.0

>>2500.34,55.2

comes in, put var1 = 2500.34 and var2 = 55.2

and so on.

---------------------EDIT----------------------------

The error I would receive that I couldn't remember from above was:

>>Terminate called after throwing an instance of 'std::out_of_range'
  what(): vector::_M_range_check: __n (which is 1) >= this->size() (which is 1)
David
  • 25
  • 5

1 Answers1

1

The answer you have found works with integers, not with floating point numbers. Anyway, the problem is very easy to solve. If you are sure about the format of your buffer (i.e. 2 floating point numbers, separated by comma, without spaces), the solution might look like this:

char buff[] = "375.5,25.3";
std::string s(buff);
std::cout << std::stof(s.substr(0, s.find(','))) << std::endl;
std::cout << std::stof(s.substr(s.find(',')+1, s.size())) << std::endl;

You can basically just use substr to create 2 substrings: one before, another after the comma, and then use stof to convert it into a floating point value.

If you need something more robust, look at this answer for more complete code to split string and catch the exceptions that might be thrown by stof.

pptaszni
  • 5,591
  • 5
  • 27
  • 43
  • two questions: 1. if I just change the int to float in the std::vector vect; that won't work? and 2. Let's say I wanted to add a third or fourth number to the buffer, would I just put std::cout << std::stof(s.substr(s.find(',')+2, s.size())) << std::endl; for the third number? – David Sep 19 '18 at 22:29
  • I'm sorry, the second question was dumb after looking at the code. But how would I handle more than two numbers? – David Sep 19 '18 at 22:36
  • You can write a function `std::vector splitString(const std::string& original, char separator)` that will return a vector of strings from the string that consists of floating point numbers separated by comma (or in general, any kind of separator). Then for each element in the vector you can apply `std::stof`. How to implement such a function is explained in another SO topic. – pptaszni Sep 20 '18 at 09:14
  • thanks. I think the function is in the SO link you put in the answer. – David Sep 20 '18 at 20:50