String doesn't accept strtok?

Hi. I'm experiencing an issue and maybe you guys could help me.

Wel..

I have a code line this:

String allinfo ="white, black, green,grey,blue" ;
String vout ;

vout = strtok(allinfo,",");

I'm trying to use strtok to get the vales I want but when I try to use the strtok, it sais:

"cannot convert 'String' to 'char*' for argument '1' to 'char* strtok(char*, const char*)'"

Any Ideas?

Tks

Don't use the String class, use a C string

String doesn't accept strtok?

No, it doesn't. So, quit trying to use Strings. Use strings (NULL terminated arrays of chars) instead.

I needs to be a char array.
Str[30] = "This is a simple NULL terminated string. ";

Also "vout = strtok(allinfo,",");" is just going to output the first word, not the full string. For that you would need a while loop and inside the while loop must be like so.

Edit: I clarified it.

char Str[] = "This is a simple NULL terminated string. ";
char * vout;

vout = strtok(Str," ");
//print first word
while(vout ! = NULL)
{
  vout = strtok(NULL, " ."); // make sure your split characters looks for something to get the last word, like a period
 // print vout
}

Str[30] = "This is a simple NULL terminated string. ";

Poor example - it looks like Str should be an array of string pointers.

char Str[] = "This is a simple NULL terminated string. ";
Str[30] = "This is a simple NULL terminated string. ";

You can't assign a string to an element of an array, regardless of what kind of array Str is, unless you do it when the array is declared. But, since the type is missing here, this isn't a declaration and initialization statement. It is an assignment statement.

Edit: I am going to have to start taking a deep breath, and see if AWOL jumps in first. Apparently, he types faster than me.

You can't assign a string to an element of an array, regardless of what kind of array Str is

?

[quote]You can't assign a string to an element of an array, regardless of what kind of array Str is[/quote]
?

Since a string is an array of chars, how can you?

o, in my case it would be like:

String allinfo ="white, black, green,grey,blue" ;
char vout [4];

vout = strtok(allinfo,",");

If not, could you PLEASe give me an example in my case?

Thank you very very much.

I fixed my example.
Aside from char Str[30] begin too small for the string I wrote, this works fine.

char Str[60] = "This is a simple NULL terminated string. ";
char * vout;

void setup()
{
  Serial.begin(9600);

  vout = strtok(Str," ");
  while(vout != NULL)
  {
    Serial.println(vout);
    vout = strtok(NULL, " ."); // make sure your split characters looks for something to get the last word, like a period
  }
}

void loop() 
{
  
}

Output:

This
is
a
simple
NULL
terminated
string

If not, could you PLEASe give me an example in my case?

How can we give you an example of something you can't do?

char stuff[] = "white, black, green,grey,blue" ;
char *token = strtok(stuff, ",");
if(token)
{
   byte count = 1;
   while(token && count < 4)
   {
      token = strtok(NULL, ",");
      count++;
   }
}

// Here, token will point to "green"

But, you can NOT do this with a String. If you insist on using Strings, look at the documentation for the String class to see how you would replicate the strtok() functionality. It will NOT be easy.

Since this appears to be related to your GPS problem, you absolutely MUST forget about Strings.

One last comment. The strtok() function will have problems when there are consecutive delimiters with nothing in between. Since the GPS returns the minimum string possible, there will often be consecutive delimiters.

You really need to determine why TinyGPS is not working, rather than trying to recreate it.

Since a string is an array of chars, how can you?

See reply #4

char* Str [10];
void setup ()
{
  Str [0] = "The quick brown fox";
}

void loop ()
{}

See reply #4

OK. You assumed that Str was an array of pointers. I did not.

Well. I think I will lose some good friends if I keep asking here about my problem;

lol.

Well..

About why the tinyGPS doesn't work. I don't know.
I am a SQL database and JAVA programmer and actually don't have much experience in C++.

I would apreciate if anyone could give me an facebook or msn address, where I could chat and ask some few things and then finish my work here today..

Why the tinyGPS is not working I don't know. I spent 2 days on it and nothing :frowning:

What I got until now, was get all gps info line by line.

That info now is in a STRING with the info separated by comma.

All I want is extract the Latidude, Longitude etc (separatelly) from this string...

could anyone dive some contact infos?

if not, I apreciate and well and I'll keep trying..
:slight_smile:

Tks a lot

HazardsMind:

char Str[60] = "This is a simple NULL terminated string. ";

If the string is not going to change then the size should not be declared explicitly.

const char stuff[] = "This is a simple NULL terminated string. ";

If the string is not going to change then the size should not be declared explicitly.

The only advantage to not explicitly declaring the size is that the compiler can count better than people. It does not mean that you can't change the characters in the array. It simply means that the length is determined for you.

But, I agree that often the size should be omitted.

HazardsMind:
But what happens if you want to change the string to something bigger ...

In that case you typically wouldn't be defining the buffer with an initial value, and you would be sizing it explicitly to make it big enough for your purpose, and you would be explicitly constraining updates to the buffer so that you don't overflow the array subsequently.

cabecinhas:
Well. I think I will lose some good friends if I keep asking here about my problem;

No you won't. Please supply us with the entire code. Someone will likely figure out what's failing.

What I got until now, was get all gps info line by line.

That info now is in a STRING with the info separated by comma.

All I want is extract the Latidude, Longitude etc (separatelly) from this string...

I don't know what a STRING is. A String (note the capitalization, is an object that has a number of properties and methods that can be used to do things to or with the contents of it.. A string (again, note the capitalization), is an array of char, which can be manipulated using C or C++ code. There is nothing you can't do with a string, that can be done with a String, though I will say that Strings are exceedingly good at wasting resources and fragmenting memory.

If you have a line from a GPS that contains a Lat, Lon, Alt, etc., you can certainly extract that data without much trouble.

could anyone dive some contact infos?

Not me. I don't do facespacetwitbook., but please, supply some code, or at the very least, a line put out by your GPS.

Deep breath, step backward. You have allinfo ="white, black, green,grey,blue" ;
and you want something like:

token[0] = "white";
token[1] = "black";
token[2] = "green";
// etc

Right? The string is to be broken apart into the pieces that are separated by the delimiter. Comma, in this case.
Yeah, this sort of thing sucks on a processor with drastically limited memory. The "algorithms" class I'm taking says that Java uses (2*N + 64) bytes to store an N-character string (this is desktop java, where a char is two bytes.) That's a lot of overhead! I assume that Arduino's String library is a little bit better, but it's still not going t be "good."
So let's use C's bare "char " structures instead; these are just pointers to arrays of characters, terminated with a null (by convention.) If we want to support, say, 20 tokens, we could have an array of 20 char pointers:char *tokens[20];
Note that this is just an array of pointers; it doesn't make any space for the characters themselves. There are a bunch of ways to set aside or allocate storage for the actual characters, but let's take the most efficient - we don't need to do anything because they are already in the string that we've read.
All we really need to do is replace all the commas (which terminate the tokens) with nulls (which terminate a C string), and keep track of where the next non-command character is. This is more or less what strtok does, but it's a bit funny. Something like:

int tokenize(char *s, char *tokens[], int maxtokens)
{
// Accept a string pointed to by s.
// update the list of comma-delimited tokens, replacing the commas with nulls.
// return the number of tokens found, not to exceed maxtokens.
// strtok does most of the work for us.
    int i;

    tokens[0] = strtok(s, ",");  // first call is special
    for (i=1; i < maxtokens; i++) {
	tokens[i] = strtok(NULL, ",");
	if (tokens[i] == NULL) {
	    break;
	}
    }
    return i;
}

Here it is, wrapped in a test program (for unix-like systems) [EDIT: now, really!]

#include <stdio.h>
#include <string.h>

#define MAXTOKENS 20

char stuff[] = "white, black, green,grey,blue" ;
char *tokens[MAXTOKENS];

int tokenize(char *s, char *tokens[], int maxtokens)
{
// Accept a string pointed to by s.
// update the list of comma-delimited tokens, replacing the commas with nulls.
// return the number of tokens found, not to exceed maxtokens.
// strtok does most of the work for us.
    int i;

    tokens[0] = strtok(s, ",");  // first call is special
    for (i=1; i < maxtokens; i++) {
	tokens[i] = strtok(NULL, ",");
	if (tokens[i] == NULL) {
	    break;
	}
    }
    return i;
}

int main()
{
    int ntokens;

    printf("Original String = %s\n", stuff);
    ntokens = tokenize(stuff, tokens, MAXTOKENS);
    printf("Parsed %d tokens\n", ntokens);
    for (int i=0; i<ntokens; i++) {
	printf("token %d = %s\n", i, tokens[i]);
    }
}