I've now used every possible way to get my problem solved, but unfortunately i didn't work.
I want to parse GET Variables. And they come from an Buffer of Ethercard.
My Shield uses the Ethercard libary by the way.
So in the Ethernode example it looks like this
if (pos) {
bfill = ether.tcpOffset();
char* data = (char *) Ethernet::buffer + pos;
#if SERIAL
Serial.println(data);
#endif
// receive buf hasn't been clobbered by reply yet
if (strncmp("GET / ", data, 6) == 0)
and it works, but i have much more possibilities of values after /.
I had several ideas to cut the string and parsing out the valuename(s) and value(s) itself.
I had several ideas to cut the string and parsing out the valuename(s) and value(s) itself.
Maybe someone could support me?
Implement one of them. Test it. If it doesn't work, post what you tried, what you actually got, and what you expected (that is what was your input and what was your output). If I were doing it, I'd be using strtok() with = as the delimiter to get a name, then with & as the delimiter to get the value, then repeat, alternating delimiters until the whole string was parsed.
could you maybe post a kind of an example?
I know it's not the mention of requesting support and starting to demand help with codesnippets but i'm now nearly crying because nothing seems to work.
Or better - i can not evaluate if it works because my tries all based on an serial output of the arduino and everytime it's starting near to a session were i will
throw my laptop out of my window.
So, data contains something like:
GET /mode=blink&rate=30&color=yellow
if (strncmp("GET / ", data, 6) == 0)
If this is true, then you can use strtok() to extract tokens.
char *token = strtok(data, "/"); // Get everything up to the /
if(token) // If we got something
{
char *name = strtok(NULL, "="); // Get the first name. Use NULL as first argument to keep parsing same string
while(name)
{
char *valu = strtok(NULL, "&");
if(valu)
{
// Do something with name and valu
name = strtok(NULL, "="); // Get the next name
}
}
}
Use NUL as first argument to keep parsing same string
NULL is here meant to be like a pointer on "token" right?
Does the while loop extract every name and value out of "token" and in this loop i have with the values
to start other programms?
like
char *name = strtok(NULL, "="); // Get the first name. Use NULL as first argument to keep parsing same string
while((name) == mode)
{
char *valu = strtok(NULL, "&");
if((valu) == blink) //Thats only if i know what the value can be else it would be if(value)
{
// Do something with name and valu
name = strtok(NULL, "="); // Get the next name
}
}
Is that interpretation right? Couldn't evaluate it by myself because im not at home til tomorrow
The strtok() function takes, as the first argument, a pointer to a string to parse. If you pass NULL as the pointer to the string to parse, strrok() keeps parsing the string it was parsing. If you pass it other than NULL, it starts parsing the new string.
Does the while loop extract every name and value out of "token" and in this loop i have with the values
to start other programms?
No, it extracts every name and every matching value out of data.
If data contains "GET / mode=blink&rate=30&color=yellow", token points to "GET / ". Then, the call to strtok() with NULL as the first argument will continue parsing "mode=blink&rate=30&color=yellow", and name will point to "mode". Then, strtok() will parse "blink&rate=30&color=yellow", and value will point to "blink".
On the next iteration of the while loop, name will point to "color" and value will point to "yellow".
I'm unfortunately not able to understand where i have to check if name = something and valu = something
and how i implement that without interrupting the parsing of the rest of "token".
So, is my example interpretation of your code right?
At the moment my opinion is that i have to compare in the while loop name with a name ( if i know the name for example in mode=blink)
#include <EtherCard.h>
// ethernet interface mac address, must be unique on the LAN
static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };
static byte myip[] = { 192,168,0,203 };
byte Ethernet::buffer[500];
BufferFiller bfill;
void setup () {
if (ether.begin(sizeof Ethernet::buffer, mymac,28) == 0)
Serial.println( "Failed to access Ethernet controller");
ether.staticSetup(myip);
pinMode(22,OUTPUT);
}
void loop () {
word len = ether.packetReceive();
word pos = ether.packetLoop(len);
char* data = (char *) Ethernet::buffer + pos;
if(strncmp("GET / ", data, 6) == 0) {
char *token = strtok(data, "/"); // Get everything up to the /
if(token) // If we got something
{
char *name = strtok(NULL, "="); // Get the first name. Use NULL as first argument to keep parsing same string
while(name == "mode")
{
char *valu = strtok(NULL, "&");
if(valu == "blink")
{
digitalWrite(22, HIGH); //YES PORT 22. It's an arduino port.
// Do something with name and valu
name = strtok(NULL, "="); // Get the next name
}
}
}
}
}
name is a pointer to a string. It will NEVER equal a constant string. They are completely different memory locations, so they will never be equal. Look at strcmp().
Ok, so now it makes more sense for me, think i understood something. Thank you for the help.
So, in my example GET / mode=blink&rate=30&color=yellow
there is a need after parsing the first name and valu to know the second and maybe the third in some situations.
But when
char *name = strtok(NULL, "="); // Get the first name. Use NULL as first argument to keep parsing same string
while(name)
{
char *valu = strtok(NULL, "&");
if(valu)
{
// Do something with name and valu
name = strtok(NULL, "="); // Get the next name
}
}
}
then name is after the second strtok the second name and that so i need to save the first.
Maybe to count name1 name2 with something like i++?
Or is there an possibility to parse it into an array? ( Like in php when you make an database query and you have $valuname[content1, content2] at the end)
I would not depend on the order of those variables. I would stick to the format I used in my code. Instead of searching for "r=" and "t=" as in my example, search for "mode=", "rate=", then add "color=" for the third variable retrieval.
what does if(strncmp("123" NULL, 3) ==0) means. Is an compare with ==0 that it is boolean true? Thought that would be 1 for true?!
Or does it means its an compare with NULL?