loop for char

Aug 2, 2014 at 6:02pm
i have a socket receving data on a char buf[256]

what i want to do is a loop to check every single char of my buf.
and if it detecs a "X=" , it add to a second variable til find a ";" and do the same when find a "Y=" til find a ";"

example

socket receive a data -> X=80.001;Y=100.400;
so
first variable "X"will be 80.001
and a
second "Y" will be 100.400
i need help, because i don't know how to do it.
Last edited on Aug 3, 2014 at 7:10pm
Aug 3, 2014 at 11:12pm
I'm old school. I'd do something like:

1
2
3
4
5
6
double x=0.0, y=0.0;

char *cp = buf-1;
while (cp = strstr(cp+1, "X=")) {
    if (scanf(cp, "X=%lf;Y=%lf", &x, &y) == 2) break;
}
Aug 4, 2014 at 10:39am
what this %lf does?
Aug 4, 2014 at 11:04am
That's new to me too.
Aug 4, 2014 at 11:58am
1
2
3
4
5
6
7
8
9
10
11
12
void CApp::OnLoop() {
float x;
float y;
char str[40]; 
csock.Translate();
char *cp = csock.rcvtxt-1;
while (cp = strstr(cp+1, "X=")) {
    if (scanf(cp, "X=%lf;Y=%lf", &x, &y) == 2) ;
sprintf(str, "%x", x);
Player.X=x;
Player.Y=y;
}


The Player won't move, looks like x and y seems to be 0;
Aug 4, 2014 at 12:22pm
http://www.cplusplus.com/reference/cstdio/scanf/

"%lf" double - if the compiler supports it
"%f" float
Aug 4, 2014 at 2:20pm
my float value is always 0.000000

there is something wrong
Aug 4, 2014 at 2:32pm
My experience with scanf is limited. Instead I approached the task using c++.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
double extract(const string & buf, string from, string to)
{
    double result = 0;
    
    size_t pos1 = buf.find(from);
    if (pos1 != string::npos)
    {
        pos1 += from.size();
        size_t pos2 = buf.find(to, pos1);
        if (pos2 != string::npos)
        {
            istringstream ss (buf.substr(pos1, pos2-pos1));
            ss >> result;
        }
    }    
    
    return result;
}

Call it like this:
double a = extract(text, "X=", ";");
Last edited on Aug 4, 2014 at 2:33pm
Aug 4, 2014 at 4:47pm
tell me all the include files i should use.
Aug 4, 2014 at 4:49pm
CApp_OnLoop.cpp:7:22: error: ‘string’ does not name a type
CApp_OnLoop.cpp:18:13: error: ‘istringstream’ was not declared in this scope
istringstream ss (buf.substr(pos1, pos2-pos1));
CApp_OnLoop.cpp:18:27: error: expected ‘;’ before ‘ss’
istringstream ss (buf.substr(pos1, pos2-pos1));
Last edited on Aug 4, 2014 at 4:49pm
Aug 4, 2014 at 5:00pm
1
2
#include <string>  // error: ‘string’ does not name a type
#include <sstream> // error: ‘istringstream’ was not declared in this scope 
Aug 4, 2014 at 5:51pm
CApp.h:82:22: error: ‘string’ does not name a type
double extract(const string & buf, string from, string to);
^
CApp.h:82:31: error: ISO C++ forbids declaration of ‘buf’ with no type [-fpermissive]
double extract(const string & buf, string from, string to);
^
CApp.h:82:36: error: ‘string’ has not been declared
double extract(const string & buf, string from, string to);
^
CApp.h:82:49: error: ‘string’ has not been declared
double extract(const string & buf, string from, string to);
Aug 4, 2014 at 5:55pm
Not sure what you're asking now. I gave the headers in the previous post.
Aug 4, 2014 at 6:21pm
i was missing using namespace, now i compiled.
is working right, with some lag, but is working.
i really don't know if is better updating the player pos everytime from server.
Last edited on Aug 4, 2014 at 6:36pm
Aug 4, 2014 at 6:29pm
Ok. I forgot also, to do things properly, I should have put std::string and std::istringstream. Sorry about that.

(or instead you could put
1
2
using std::string;
using std::istringstream;
somewhere before this function).
Last edited on Aug 4, 2014 at 6:40pm
Aug 4, 2014 at 7:06pm
I did consider that my approach might be a little slower than using C-based code. But possibly the lag may be due to the server connection.
Aug 4, 2014 at 7:16pm
ok, thanks
Aug 4, 2014 at 7:31pm
Still, here's an alternative:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <cstdlib>
#include <cstring>

double xtract(const char * buf, const char * from)
{
    double result = 0;
    
    const char * pos = strstr(buf, from);
    
    if (pos != NULL)
        result = atof(pos+strlen(from));
    
    return result;
}


call like this:
 
double a = xtract(text, "X=" );

It may be somewhat faster. Or don't use a function call, just put the code inline, and replace strlen(from) with the actual length (2 in this case).
Last edited on Aug 4, 2014 at 8:00pm
Aug 5, 2014 at 11:00am
the first option is fine for me, is working fast too.
Topic archived. No new replies allowed.