parsing string into an array

J

John Smith

I would like to parse a string into an array. I found on the net
the following codes which parse a string and print it. The result
is exactly what I want:

char * pch;
pch = strtok (buffer," ");
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, " ,.");
}

To store the output to a string array, I created a two-dimensional
array and copied the output to the array:

char output[5][55];
char * pch;
int i=0;
pch = strtok (str," ");
while (pch != NULL)
{
strcpy(output,pch);
printf ("%s\n",pch);
printf("output[%d] is %s.\n";i,output[i++]);
pch = strtok (NULL, " ,.");
}

This doesn't work. What's in the output array is nothing like the
output (on screen). How should it be done?
 
W

Walter Roberson

John Smith said:
printf("output[%d] is %s.\n";i,output[i++]);

If I recall correctly, this uses undefined behaviour.
The post increment may be done at any time between the
sequence points, so it is not defined whether the first
reference to i has its value taken before or after the
increment.

It also is a syntax error to have the semicolon in the middle
of the statement. That line should not compile at all.
 
J

John Smith

Walter said:
printf("output[%d] is %s.\n";i,output[i++]);


If I recall correctly, this uses undefined behaviour.
The post increment may be done at any time between the
sequence points, so it is not defined whether the first
reference to i has its value taken before or after the
increment.

It also is a syntax error to have the semicolon in the middle
of the statement. That line should not compile at all.

Thanks for the reply. That semicolon was a typo.

Actually, I had also tried the following (a separate i++) and it
did not work either.

char output[5][55];
char * pch;
int i=0;
pch = strtok (str," ");
while (pch != NULL)
{
strcpy(output,pch);
printf ("%s\n",pch);
printf("output[%d] is %s.\n",i,output);
i++;
pch = strtok (NULL, " ,.");
}
 
A

Al Bowers

John said:
Actually, I had also tried the following (a separate i++) and it
did not work either.

char output[5][55];
char * pch;
int i=0;
pch = strtok (str," ");
while (pch != NULL)
{
strcpy(output,pch);
printf ("%s\n",pch);
printf("output[%d] is %s.\n",i,output);
i++;
pch = strtok (NULL, " ,.");
}


The code provided here seems to be ok. What do you
mean by "did not work either".
 
J

Joe Estock

John said:
I would like to parse a string into an array. I found on the net
the following codes which parse a string and print it. The result
is exactly what I want:

char * pch;
pch = strtok (buffer," ");
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, " ,.");
}

To store the output to a string array, I created a two-dimensional
array and copied the output to the array:

char output[5][55];
char * pch;
int i=0;
pch = strtok (str," ");
while (pch != NULL)
{
strcpy(output,pch);
printf ("%s\n",pch);
printf("output[%d] is %s.\n";i,output[i++]);
pch = strtok (NULL, " ,.");
}

This doesn't work. What's in the output array is nothing like the
output (on screen). How should it be done?

Smells like a buffer overflow to me.
 
G

Guillaume

John said:
To store the output to a string array, I created a two-dimensional
array and copied the output to the array:

char output[5][55];
(snip)
This doesn't work. What's in the output array is nothing like the
output (on screen). How should it be done?

Are you aware that this will fail if:
* there are more than 5 "tokens"
* one or more of the tokens is (are) longer than 54 characters

That said, there are a couple more things to know:
* strtok() alters the string it works on. So you can't use
it to parse the same string twice unless you have made a copy
of this string before. This may be what happens to you if
your program tries both of your parsing attempts one after
the other on the same string.
* strtok() is one of those "evilish" C std library functions,
because it maintains an internal structure and thus cannot be
used in nested calls. So you must use it with a lot of care,
and it really is safe only in the simplest programs (unless
you really know what you're doing).
Not worth it in my opinion, since it's so easy to implement
"by hand" in a safe manner.

As a side note, I will add that outside of textbooks, multidimensional
arrays in C are not particularly useful. Their syntax is often
misleading (in my opinion) and they can serve only very limited
purpose. I tend to prefer arrays of arrays, which are easier to handle
and more flexible (in my opinion).
 
J

Joe Wright

John said:
Walter said:
printf("output[%d] is %s.\n";i,output[i++]);


If I recall correctly, this uses undefined behaviour.
The post increment may be done at any time between the
sequence points, so it is not defined whether the first
reference to i has its value taken before or after the
increment.

It also is a syntax error to have the semicolon in the middle
of the statement. That line should not compile at all.


Thanks for the reply. That semicolon was a typo.

Actually, I had also tried the following (a separate i++) and it
did not work either.

char output[5][55];
char * pch;
int i=0;
pch = strtok (str," ");
while (pch != NULL)
{
strcpy(output,pch);
printf ("%s\n",pch);
printf("output[%d] is %s.\n",i,output);
i++;
pch = strtok (NULL, " ,.");
}


Hi John,
(Do us a favor. See if you can turn off the annoying MIME stuff)
Like Al, I can't see what "did not work". Of course, you have not shown
us what the original 'char *str = "...";' looks like, or where you get
it. Enquiring Minds want to know.
 
C

CBFalconer

Joe said:
John said:
Walter said:
printf("output[%d] is %s.\n";i,output[i++]);

If I recall correctly, this uses undefined behaviour. .... snip ...

It also is a syntax error to have the semicolon in the middle
of the statement. That line should not compile at all.

Thanks for the reply. That semicolon was a typo.

Actually, I had also tried the following (a separate i++) and it
did not work either.
.... snip ...

(Do us a favor. See if you can turn off the annoying MIME stuff)
.... snip ...

I am among the first to bitch and moan about mime and html in
Usenet, but I see none in this thread. Has something stripped it
on the path from there to here?
 
J

John Smith

Thanks to those who replied to my queston. I appreciate your help.
The code did work. I wasn't aware strtok would change the original
string. That caused some confusion.

(Is MIME turned off this time? Hope it is.)
 
J

Joe Wright

John said:
Thanks to those who replied to my queston. I appreciate your help.
The code did work. I wasn't aware strtok would change the original
string. That caused some confusion.

(Is MIME turned off this time? Hope it is.)

I can't tell about MIME anymore. After I wrote my note to you I've set
Thunderbird to ignore it.
 
J

Joe Wright

CBFalconer said:
Joe Wright wrote:

... snip ...


... snip ...

I am among the first to bitch and moan about mime and html in
Usenet, but I see none in this thread. Has something stripped it
on the path from there to here?

I suspect you have turned it off in your reader, as I now have.
 
W

Walter Roberson

I am among the first to bitch and moan about mime and html in
Usenet, but I see none in this thread. Has something stripped it
on the path from there to here?

It isn't the typical obvious MIME so my reader (trn) didn't notice
it either. He did, though, have a Content-type: text/plain
header that specified a charset of Big5. Content-Type is a MIME
header, and on some systems the Big5 (i.e., one of the Chinese
encodings) would trigger different behaviour than if it were
(say) 8859-1 .
 
K

Keith Thompson

Guillaume said:
John said:
To store the output to a string array, I created a two-dimensional
array and copied the output to the array:

char output[5][55];
(snip)
This doesn't work. What's in the output array is nothing like the
output (on screen). How should it be done?
[snip]
As a side note, I will add that outside of textbooks, multidimensional
arrays in C are not particularly useful. Their syntax is often
misleading (in my opinion) and they can serve only very limited
purpose. I tend to prefer arrays of arrays, which are easier to handle
and more flexible (in my opinion).

I'm not certain what distinction you're making here. The declaration
char output[5][55];
defines output as an array of arrays of char, which is the closest
thing C has to a multi-dimensional array.

Perhaps you're thinking of an array of pointers to arrays?
 
C

Christopher Benson-Manica

John Smith said:
(Is MIME turned off this time? Hope it is.)

It seems not to be - the header that Walter referred to is still
present:

Content-Type: text/plain; charset=Big5

although it also looks like the people it annoys have been able to
change their newsreader configuration, so you may not have to worry
about it (tin has not complained about it here, FWIW).
 
C

CBFalconer

Christopher said:
It seems not to be - the header that Walter referred to is still
present:

Content-Type: text/plain; charset=Big5

although it also looks like the people it annoys have been able to
change their newsreader configuration, so you may not have to worry
about it (tin has not complained about it here, FWIW).

There is no attached mime section, nor any html. So I see no harm
in it, although I am one of the most vocal html/mime haters
extant.
 
D

Default User

Christopher said:
It seems not to be - the header that Walter referred to is still
present:

Content-Type: text/plain; charset=Big5

although it also looks like the people it annoys have been able to
change their newsreader configuration, so you may not have to worry
about it (tin has not complained about it here, FWIW).


All it does for me is change the font from the default to a sans-serif
one. It's annoying to a certain extent, but not a killer. I haven't
figured out how to make XanaNews ignore it, if even possible.



Brian
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,072
Latest member
trafficcone

Latest Threads

Top